|
|
d1681e |
From 27081fda822921e7f452304bea170d2d13cba257 Mon Sep 17 00:00:00 2001
|
|
|
d1681e |
From: Mohit Agrawal <moagrawa@redhat.com>
|
|
|
d1681e |
Date: Fri, 12 May 2017 21:12:47 +0530
|
|
|
d1681e |
Subject: [PATCH 205/212] cluster/dht : User xattrs are not healed after brick
|
|
|
d1681e |
stop/start
|
|
|
d1681e |
|
|
|
d1681e |
Problem: In a distributed volume custom extended attribute value for a directory
|
|
|
d1681e |
does not display correct value after stop/start or added newly brick.
|
|
|
d1681e |
If any extended(acl) attribute value is set for a directory after stop/added
|
|
|
d1681e |
the brick the attribute(user|acl|quota) value is not updated on brick
|
|
|
d1681e |
after start the brick.
|
|
|
d1681e |
|
|
|
d1681e |
Solution: First store hashed subvol or subvol(has internal xattr) on inode ctx and
|
|
|
d1681e |
consider it as a MDS subvol.At the time of update custom xattr
|
|
|
d1681e |
(user,quota,acl, selinux) on directory first check the mds from
|
|
|
d1681e |
inode ctx, if mds is not present on inode ctx then throw EINVAL error
|
|
|
d1681e |
to application otherwise set xattr on MDS subvol with internal xattr
|
|
|
d1681e |
value of -1 and then try to update the attribute on other non MDS
|
|
|
d1681e |
volumes also.If mds subvol is down in that case throw an
|
|
|
d1681e |
error "Transport endpoint is not connected". In dht_dir_lookup_cbk|
|
|
|
d1681e |
dht_revalidate_cbk|dht_discover_complete call dht_call_dir_xattr_heal
|
|
|
d1681e |
to heal custom extended attribute.
|
|
|
d1681e |
In case of gnfs server if hashed subvol has not found based on
|
|
|
d1681e |
loc then wind a call on all subvol to update xattr.
|
|
|
d1681e |
|
|
|
d1681e |
Fix: 1) Save MDS subvol on inode ctx
|
|
|
d1681e |
2) Check if mds subvol is present on inode ctx
|
|
|
d1681e |
3) If mds subvol is down then call unwind with error ENOTCONN and if it is up
|
|
|
d1681e |
then set new xattr "GF_DHT_XATTR_MDS" to -1 and wind a call on other
|
|
|
d1681e |
subvol.
|
|
|
d1681e |
4) If setxattr fop is successful on non-mds subvol then increment the value of
|
|
|
d1681e |
internal xattr to +1
|
|
|
d1681e |
5) At the time of directory_lookup check the value of new xattr GF_DHT_XATTR_MDS
|
|
|
d1681e |
6) If value is not 0 in dht_lookup_dir_cbk(other cbk) functions then call heal
|
|
|
d1681e |
function to heal user xattr
|
|
|
d1681e |
7) syncop_setxattr on hashed_subvol to reset the value of xattr to 0
|
|
|
d1681e |
if heal is successful on all subvol.
|
|
|
d1681e |
|
|
|
d1681e |
Test : To reproduce the issue followed below steps
|
|
|
d1681e |
1) Create a distributed volume and create mount point
|
|
|
d1681e |
2) Create some directory from mount point mkdir tmp{1..5}
|
|
|
d1681e |
3) Kill any one brick from the volume
|
|
|
d1681e |
4) Set extended attribute from mount point on directory
|
|
|
d1681e |
setfattr -n user.foo -v "abc" ./tmp{1..5}
|
|
|
d1681e |
It will throw error " Transport End point is not connected "
|
|
|
d1681e |
for those hashed subvol is down
|
|
|
d1681e |
5) Start volume with force option to start brick process
|
|
|
d1681e |
6) Execute getfattr command on mount point for directory
|
|
|
d1681e |
7) Check extended attribute on brick
|
|
|
d1681e |
getfattr -n user.foo <volume-location>/tmp{1..5}
|
|
|
d1681e |
It shows correct value for directories for those
|
|
|
d1681e |
xattr fop were executed successfully.
|
|
|
d1681e |
|
|
|
d1681e |
Note: The patch will resolve xattr healing problem only for fuse mount
|
|
|
d1681e |
not for nfs mount.
|
|
|
d1681e |
|
|
|
d1681e |
> BUG: 1371806
|
|
|
d1681e |
> Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
|
|
|
d1681e |
> (Cherry pick from commit 9b4de61a136b8e5ba7bf0e48690cdb1292d0dee8)
|
|
|
d1681e |
> (Upstream patch link https://review.gluster.org/#/c/15468/)
|
|
|
d1681e |
|
|
|
d1681e |
BUG: 1550315
|
|
|
d1681e |
Change-Id: I4eb137eace24a8cb796712b742f1d177a65343d5
|
|
|
d1681e |
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
|
|
|
d1681e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/132383
|
|
|
d1681e |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
d1681e |
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
|
|
|
d1681e |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
d1681e |
---
|
|
|
d1681e |
tests/bugs/bug-1368312.t | 30 +-
|
|
|
d1681e |
tests/bugs/bug-1371806.t | 80 ++
|
|
|
d1681e |
tests/bugs/bug-1371806_1.t | 49 +
|
|
|
d1681e |
tests/bugs/bug-1371806_2.t | 52 ++
|
|
|
d1681e |
tests/bugs/bug-1371806_3.t | 63 ++
|
|
|
d1681e |
tests/bugs/bug-1371806_acl.t | 90 ++
|
|
|
d1681e |
tests/bugs/distribute/bug-862967.t | 7 +-
|
|
|
d1681e |
xlators/cluster/dht/src/dht-common.c | 1389 ++++++++++++++++++++++++++---
|
|
|
d1681e |
xlators/cluster/dht/src/dht-common.h | 72 +-
|
|
|
d1681e |
xlators/cluster/dht/src/dht-helper.c | 65 ++
|
|
|
d1681e |
xlators/cluster/dht/src/dht-inode-write.c | 163 +++-
|
|
|
d1681e |
xlators/cluster/dht/src/dht-messages.h | 28 +-
|
|
|
d1681e |
xlators/cluster/dht/src/dht-selfheal.c | 519 ++++++++++-
|
|
|
d1681e |
xlators/cluster/dht/src/dht-shared.c | 2 +
|
|
|
d1681e |
14 files changed, 2436 insertions(+), 173 deletions(-)
|
|
|
d1681e |
create mode 100644 tests/bugs/bug-1371806.t
|
|
|
d1681e |
create mode 100644 tests/bugs/bug-1371806_1.t
|
|
|
d1681e |
create mode 100644 tests/bugs/bug-1371806_2.t
|
|
|
d1681e |
create mode 100644 tests/bugs/bug-1371806_3.t
|
|
|
d1681e |
create mode 100644 tests/bugs/bug-1371806_acl.t
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/tests/bugs/bug-1368312.t b/tests/bugs/bug-1368312.t
|
|
|
d1681e |
index 135048f..61e5606 100644
|
|
|
d1681e |
--- a/tests/bugs/bug-1368312.t
|
|
|
d1681e |
+++ b/tests/bugs/bug-1368312.t
|
|
|
d1681e |
@@ -29,46 +29,46 @@ TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0;
|
|
|
d1681e |
TEST mkdir $M0/tmp1
|
|
|
d1681e |
|
|
|
d1681e |
#Create metadata split-brain
|
|
|
d1681e |
-TEST kill_brick $V0 $H0 $B0/${V0}0
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}2
|
|
|
d1681e |
TEST chmod 666 $M0/tmp1
|
|
|
d1681e |
TEST $CLI volume start $V0 force
|
|
|
d1681e |
-TEST kill_brick $V0 $H0 $B0/${V0}1
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}3
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2
|
|
|
d1681e |
|
|
|
d1681e |
TEST chmod 757 $M0/tmp1
|
|
|
d1681e |
|
|
|
d1681e |
TEST $CLI volume start $V0 force
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 3
|
|
|
d1681e |
|
|
|
d1681e |
EXPECT 2 get_pending_heal_count $V0
|
|
|
d1681e |
|
|
|
d1681e |
|
|
|
d1681e |
-TEST kill_brick $V0 $H0 $B0/${V0}2
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}4
|
|
|
d1681e |
TEST chmod 755 $M0/tmp1
|
|
|
d1681e |
TEST $CLI volume start $V0 force
|
|
|
d1681e |
-TEST kill_brick $V0 $H0 $B0/${V0}3
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}5
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4
|
|
|
d1681e |
|
|
|
d1681e |
TEST chmod 766 $M0/tmp1
|
|
|
d1681e |
|
|
|
d1681e |
TEST $CLI volume start $V0 force
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 3
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 5
|
|
|
d1681e |
|
|
|
d1681e |
EXPECT 4 get_pending_heal_count $V0
|
|
|
d1681e |
|
|
|
d1681e |
-TEST kill_brick $V0 $H0 $B0/${V0}4
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}0
|
|
|
d1681e |
TEST chmod 765 $M0/tmp1
|
|
|
d1681e |
TEST $CLI volume start $V0 force
|
|
|
d1681e |
-TEST kill_brick $V0 $H0 $B0/${V0}5
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}1
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
d1681e |
|
|
|
d1681e |
TEST chmod 756 $M0/tmp1
|
|
|
d1681e |
|
|
|
d1681e |
TEST $CLI volume start $V0 force
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 4
|
|
|
d1681e |
-EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 5
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
|
|
|
d1681e |
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
|
|
|
d1681e |
|
|
|
d1681e |
EXPECT 6 get_pending_heal_count $V0
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/tests/bugs/bug-1371806.t b/tests/bugs/bug-1371806.t
|
|
|
d1681e |
new file mode 100644
|
|
|
d1681e |
index 0000000..7dc1613
|
|
|
d1681e |
--- /dev/null
|
|
|
d1681e |
+++ b/tests/bugs/bug-1371806.t
|
|
|
d1681e |
@@ -0,0 +1,80 @@
|
|
|
d1681e |
+#!/bin/bash
|
|
|
d1681e |
+. $(dirname $0)/../include.rc
|
|
|
d1681e |
+. $(dirname $0)/../volume.rc
|
|
|
d1681e |
+. $(dirname $0)/../dht.rc
|
|
|
d1681e |
+cleanup;
|
|
|
d1681e |
+
|
|
|
d1681e |
+function get_getfattr {
|
|
|
d1681e |
+ local path=$1
|
|
|
d1681e |
+ echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//'
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+function set_fattr {
|
|
|
d1681e |
+ for i in `seq 1 10`
|
|
|
d1681e |
+ do
|
|
|
d1681e |
+ setfattr -n user.foo -v "newabc" ./tmp${i}
|
|
|
d1681e |
+ if [ "$?" = "0" ]
|
|
|
d1681e |
+ then
|
|
|
d1681e |
+ succ=$((succ+1))
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ fail=$((fail+1))
|
|
|
d1681e |
+ fi
|
|
|
d1681e |
+ done
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterd
|
|
|
d1681e |
+TEST pidof glusterd
|
|
|
d1681e |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3,4,5}
|
|
|
d1681e |
+TEST $CLI volume start $V0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+TEST mkdir tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+##First set user.foo xattr with value abc on all dirs
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST setfattr -n user.foo -v "abc" ./tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr ./tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr $B0/${V0}5/tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}5
|
|
|
d1681e |
+EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "5" online_brick_count
|
|
|
d1681e |
+
|
|
|
d1681e |
+succ=fail=0
|
|
|
d1681e |
+## set user.foo xattr with value newabc after kill one brick
|
|
|
d1681e |
+set_fattr
|
|
|
d1681e |
+TEST $CLI volume start $V0 force
|
|
|
d1681e |
+EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "6" online_brick_count
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+TEST umount $M0
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+## At this point dht code will heal xattr on down brick only for those dirs
|
|
|
d1681e |
+## hashed subvol was up at the time of update xattr
|
|
|
d1681e |
+TEST stat ./tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+## Count the user.foo xattr value with abc on mount point and compare with fail value
|
|
|
d1681e |
+count=`getfattr -n user.foo ./tmp{1..10} | grep "user.foo" | grep -iw "abc" | wc -l`
|
|
|
d1681e |
+EXPECT "$fail" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+## Count the user.foo xattr value with newabc on mount point and compare with succ value
|
|
|
d1681e |
+count=`getfattr -n user.foo ./tmp{1..10} | grep "user.foo" | grep -iw "newabc" | wc -l`
|
|
|
d1681e |
+EXPECT "$succ" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+## Count the user.foo xattr value with abc on brick and compare with succ value
|
|
|
d1681e |
+count=`getfattr -n user.foo $B0/${V0}5/tmp{1..10} | grep "user.foo" | grep -iw "abc" | wc -l`
|
|
|
d1681e |
+EXPECT "$fail" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+## Count the user.foo xattr value with newabc on brick and compare with succ value
|
|
|
d1681e |
+count=`getfattr -n user.foo $B0/${V0}5/tmp{1..10} | grep "user.foo" | grep -iw "newabc" | wc -l`
|
|
|
d1681e |
+EXPECT "$succ" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
+exit
|
|
|
d1681e |
diff --git a/tests/bugs/bug-1371806_1.t b/tests/bugs/bug-1371806_1.t
|
|
|
d1681e |
new file mode 100644
|
|
|
d1681e |
index 0000000..44a57a9
|
|
|
d1681e |
--- /dev/null
|
|
|
d1681e |
+++ b/tests/bugs/bug-1371806_1.t
|
|
|
d1681e |
@@ -0,0 +1,49 @@
|
|
|
d1681e |
+#!/bin/bash
|
|
|
d1681e |
+. $(dirname $0)/../include.rc
|
|
|
d1681e |
+. $(dirname $0)/../volume.rc
|
|
|
d1681e |
+. $(dirname $0)/../dht.rc
|
|
|
d1681e |
+cleanup;
|
|
|
d1681e |
+
|
|
|
d1681e |
+function get_getfattr {
|
|
|
d1681e |
+ local path=$1
|
|
|
d1681e |
+ echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//'
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+function remove_mds_xattr {
|
|
|
d1681e |
+
|
|
|
d1681e |
+ for i in `seq 1 10`
|
|
|
d1681e |
+ do
|
|
|
d1681e |
+ setfattr -x trusted.glusterfs.dht.mds $1/tmp${i} 2> /dev/null
|
|
|
d1681e |
+ done
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterd
|
|
|
d1681e |
+TEST pidof glusterd
|
|
|
d1681e |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3}
|
|
|
d1681e |
+TEST $CLI volume start $V0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+TEST mkdir tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+##Remove internal mds xattr from all directory
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}0
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}1
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}2
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}3
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+umount $M0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0;
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST setfattr -n user.foo -v "abc" ./tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr ./tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
+exit
|
|
|
d1681e |
diff --git a/tests/bugs/bug-1371806_2.t b/tests/bugs/bug-1371806_2.t
|
|
|
d1681e |
new file mode 100644
|
|
|
d1681e |
index 0000000..e6aa8e7
|
|
|
d1681e |
--- /dev/null
|
|
|
d1681e |
+++ b/tests/bugs/bug-1371806_2.t
|
|
|
d1681e |
@@ -0,0 +1,52 @@
|
|
|
d1681e |
+#!/bin/bash
|
|
|
d1681e |
+. $(dirname $0)/../include.rc
|
|
|
d1681e |
+. $(dirname $0)/../volume.rc
|
|
|
d1681e |
+. $(dirname $0)/../dht.rc
|
|
|
d1681e |
+cleanup;
|
|
|
d1681e |
+
|
|
|
d1681e |
+function get_getfattr {
|
|
|
d1681e |
+ local path=$1
|
|
|
d1681e |
+ echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//'
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+function remove_mds_xattr {
|
|
|
d1681e |
+
|
|
|
d1681e |
+ for i in `seq 1 10`
|
|
|
d1681e |
+ do
|
|
|
d1681e |
+ setfattr -x trusted.glusterfs.dht.mds $1/tmp${i} 2> /dev/null
|
|
|
d1681e |
+ done
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterd
|
|
|
d1681e |
+TEST pidof glusterd
|
|
|
d1681e |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3}
|
|
|
d1681e |
+TEST $CLI volume start $V0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 --attribute-timeout=0 $M0;
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+TEST mkdir tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+##Remove internal mds xattr from all directory
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}0
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}1
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}2
|
|
|
d1681e |
+remove_mds_xattr $B0/${V0}3
|
|
|
d1681e |
+
|
|
|
d1681e |
+##First set user.foo xattr with value abc on all dirs
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST setfattr -n user.foo -v "abc" ./tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr ./tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr $B0/${V0}0/tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr $B0/${V0}1/tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr $B0/${V0}2/tmp{1..10}
|
|
|
d1681e |
+EXPECT "abc" get_getfattr $B0/${V0}3/tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+TEST umount $M0
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
+exit
|
|
|
d1681e |
diff --git a/tests/bugs/bug-1371806_3.t b/tests/bugs/bug-1371806_3.t
|
|
|
d1681e |
new file mode 100644
|
|
|
d1681e |
index 0000000..cb13f37
|
|
|
d1681e |
--- /dev/null
|
|
|
d1681e |
+++ b/tests/bugs/bug-1371806_3.t
|
|
|
d1681e |
@@ -0,0 +1,63 @@
|
|
|
d1681e |
+#!/bin/bash
|
|
|
d1681e |
+. $(dirname $0)/../include.rc
|
|
|
d1681e |
+. $(dirname $0)/../volume.rc
|
|
|
d1681e |
+. $(dirname $0)/../dht.rc
|
|
|
d1681e |
+cleanup;
|
|
|
d1681e |
+
|
|
|
d1681e |
+function get_getfattr {
|
|
|
d1681e |
+ local path=$1
|
|
|
d1681e |
+ echo `getfattr -n user.foo $path` | cut -f2 -d"=" | sed -e 's/^"//' -e 's/"$//'
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+function set_fattr {
|
|
|
d1681e |
+ for i in `seq 1 10`
|
|
|
d1681e |
+ do
|
|
|
d1681e |
+ setfattr -n user.foo -v "newabc" ./tmp${i}
|
|
|
d1681e |
+ if [ "$?" = "0" ]
|
|
|
d1681e |
+ then
|
|
|
d1681e |
+ succ=$((succ+1))
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ fail=$((fail+1))
|
|
|
d1681e |
+ fi
|
|
|
d1681e |
+ done
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterd
|
|
|
d1681e |
+TEST pidof glusterd
|
|
|
d1681e |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3}
|
|
|
d1681e |
+TEST $CLI volume start $V0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 --attribute-timeout=0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+TEST mkdir tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}3
|
|
|
d1681e |
+EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "3" online_brick_count
|
|
|
d1681e |
+
|
|
|
d1681e |
+succ=fail=0
|
|
|
d1681e |
+## set user.foo xattr with value newabc after kill one brick
|
|
|
d1681e |
+set_fattr
|
|
|
d1681e |
+TEST $CLI volume start $V0 force
|
|
|
d1681e |
+EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "4" online_brick_count
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+TEST umount $M0
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 --entry-timeout=0 --attribute-timeout=0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+## At this point dht code will heal xattr on down brick only for those dirs
|
|
|
d1681e |
+## hashed subvol was up at the time of update xattr
|
|
|
d1681e |
+TEST stat ./tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+## Count the user.foo xattr value with newabc on brick and compare with succ value
|
|
|
d1681e |
+count=`getfattr -n user.foo $B0/${V0}3/tmp{1..10} | grep "user.foo" | grep -iw "newabc" | wc -l`
|
|
|
d1681e |
+EXPECT "$succ" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
+exit
|
|
|
d1681e |
diff --git a/tests/bugs/bug-1371806_acl.t b/tests/bugs/bug-1371806_acl.t
|
|
|
d1681e |
new file mode 100644
|
|
|
d1681e |
index 0000000..aa41e04
|
|
|
d1681e |
--- /dev/null
|
|
|
d1681e |
+++ b/tests/bugs/bug-1371806_acl.t
|
|
|
d1681e |
@@ -0,0 +1,90 @@
|
|
|
d1681e |
+#!/bin/bash
|
|
|
d1681e |
+. $(dirname $0)/../include.rc
|
|
|
d1681e |
+. $(dirname $0)/../volume.rc
|
|
|
d1681e |
+
|
|
|
d1681e |
+cleanup;
|
|
|
d1681e |
+TEST useradd tmpuser
|
|
|
d1681e |
+
|
|
|
d1681e |
+function set_facl_user {
|
|
|
d1681e |
+ for i in `seq 1 10`
|
|
|
d1681e |
+ do
|
|
|
d1681e |
+ setfacl -m u:tmpuser:rw ./tmp${i}
|
|
|
d1681e |
+ if [ "$?" = "0" ]
|
|
|
d1681e |
+ then
|
|
|
d1681e |
+ succ=$((succ+1))
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ fail=$((fail+1))
|
|
|
d1681e |
+ fi
|
|
|
d1681e |
+ done
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+function set_facl_default {
|
|
|
d1681e |
+ for i in `seq 1 10`
|
|
|
d1681e |
+ do
|
|
|
d1681e |
+ setfacl -m d:o:rw ./tmp${i}
|
|
|
d1681e |
+ if [ "$?" = "0" ]
|
|
|
d1681e |
+ then
|
|
|
d1681e |
+ succ1=$((succ1+1))
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ fail1=$((fail1+1))
|
|
|
d1681e |
+ fi
|
|
|
d1681e |
+ done
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterd
|
|
|
d1681e |
+TEST pidof glusterd
|
|
|
d1681e |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1,2,3,4,5}
|
|
|
d1681e |
+TEST $CLI volume set $V0 diagnostics.client-log-level DEBUG
|
|
|
d1681e |
+TEST $CLI volume start $V0
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --acl --volfile-server=$H0 --entry-timeout=0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+TEST mkdir tmp{1..10}
|
|
|
d1681e |
+TEST setfacl -m u:tmpuser:rwx ./tmp{1..10}
|
|
|
d1681e |
+count=`getfacl -p $M0/tmp{1..10} | grep -c "user:tmpuser:rwx"`
|
|
|
d1681e |
+EXPECT "10" echo $count
|
|
|
d1681e |
+TEST setfacl -m d:o:rwx ./tmp{1..10}
|
|
|
d1681e |
+count=`getfacl -p $M0/tmp{1..10} | grep -c "default:other::rwx"`
|
|
|
d1681e |
+EXPECT "10" echo $count
|
|
|
d1681e |
+count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "user:tmpuser:rwx"`
|
|
|
d1681e |
+EXPECT "10" echo $count
|
|
|
d1681e |
+count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "default:other::rwx"`
|
|
|
d1681e |
+EXPECT "10" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST kill_brick $V0 $H0 $B0/${V0}5
|
|
|
d1681e |
+EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "5" online_brick_count
|
|
|
d1681e |
+
|
|
|
d1681e |
+succ=fail=0
|
|
|
d1681e |
+## Update acl attributes on dir after kill one brick
|
|
|
d1681e |
+set_facl_user
|
|
|
d1681e |
+succ1=fail1=0
|
|
|
d1681e |
+set_facl_default
|
|
|
d1681e |
+
|
|
|
d1681e |
+TEST $CLI volume start $V0 force
|
|
|
d1681e |
+EXPECT_WITHIN ${PROCESS_UP_TIMEOUT} "6" online_brick_count
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+TEST umount $M0
|
|
|
d1681e |
+TEST glusterfs --volfile-id=$V0 --acl --volfile-server=$H0 --entry-timeout=0 $M0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd $M0
|
|
|
d1681e |
+## At this point dht will heal xatts on down brick only for those hashed_subvol
|
|
|
d1681e |
+## was up at the time of updated xattrs
|
|
|
d1681e |
+TEST stat ./tmp{1..10}
|
|
|
d1681e |
+
|
|
|
d1681e |
+## Compare succ value with updated acl attributes
|
|
|
d1681e |
+count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "user:tmpuser:rw-"`
|
|
|
d1681e |
+EXPECT "$succ" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+count=`getfacl -p $B0/${V0}5/tmp{1..10} | grep -c "default:other::rw-"`
|
|
|
d1681e |
+EXPECT "$succ1" echo $count
|
|
|
d1681e |
+
|
|
|
d1681e |
+cd -
|
|
|
d1681e |
+userdel --force tmpuser
|
|
|
d1681e |
+cleanup
|
|
|
d1681e |
diff --git a/tests/bugs/distribute/bug-862967.t b/tests/bugs/distribute/bug-862967.t
|
|
|
d1681e |
index 09dac37..2fb0848 100644
|
|
|
d1681e |
--- a/tests/bugs/distribute/bug-862967.t
|
|
|
d1681e |
+++ b/tests/bugs/distribute/bug-862967.t
|
|
|
d1681e |
@@ -37,7 +37,7 @@ chown 1:1 $M0/dir;
|
|
|
d1681e |
|
|
|
d1681e |
# Kill a brick process
|
|
|
d1681e |
|
|
|
d1681e |
-kill_brick $V0 $H0 $B0/${V0}1
|
|
|
d1681e |
+kill_brick $V0 $H0 $B0/${V0}2
|
|
|
d1681e |
# change dir ownership
|
|
|
d1681e |
NEW_UID=36;
|
|
|
d1681e |
NEW_GID=36;
|
|
|
d1681e |
@@ -51,9 +51,8 @@ sleep 10;
|
|
|
d1681e |
ls -l $M0/dir;
|
|
|
d1681e |
|
|
|
d1681e |
# check if uid/gid is healed on backend brick which was taken down
|
|
|
d1681e |
-BACKEND_UID=`stat -c %u $B0/${V0}1/dir`;
|
|
|
d1681e |
-BACKEND_GID=`stat -c %g $B0/${V0}1/dir`;
|
|
|
d1681e |
-
|
|
|
d1681e |
+BACKEND_UID=`stat -c %u $B0/${V0}2/dir`;
|
|
|
d1681e |
+BACKEND_GID=`stat -c %g $B0/${V0}2/dir`;
|
|
|
d1681e |
|
|
|
d1681e |
EXPECT "0" uid_gid_compare $NEW_UID $NEW_GID $BACKEND_UID $BACKEND_GID
|
|
|
d1681e |
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
|
|
|
d1681e |
index 5641330..f1e6a92 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-common.c
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-common.c
|
|
|
d1681e |
@@ -110,6 +110,24 @@ int dht_read_iatt_from_xdata (xlator_t *this, dict_t *xdata,
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_rmdir_unlock (call_frame_t *frame, xlator_t *this);
|
|
|
d1681e |
|
|
|
d1681e |
+char *xattrs_to_heal[] = {
|
|
|
d1681e |
+ "user.",
|
|
|
d1681e |
+ POSIX_ACL_ACCESS_XATTR,
|
|
|
d1681e |
+ POSIX_ACL_DEFAULT_XATTR,
|
|
|
d1681e |
+ QUOTA_LIMIT_KEY,
|
|
|
d1681e |
+ QUOTA_LIMIT_OBJECTS_KEY,
|
|
|
d1681e |
+ GF_SELINUX_XATTR_KEY,
|
|
|
d1681e |
+ NULL
|
|
|
d1681e |
+};
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Return true if key exists in array
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+static gf_boolean_t
|
|
|
d1681e |
+dht_match_xattr (const char *key)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ return gf_get_index_by_elem (xattrs_to_heal, (char *)key) >= 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_aggregate_quota_xattr (dict_t *dst, char *key, data_t *value)
|
|
|
d1681e |
{
|
|
|
d1681e |
@@ -205,7 +223,7 @@ int add_opt(char **optsp, const char *opt)
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
/* Return Choice list from Split brain status */
|
|
|
d1681e |
-char *
|
|
|
d1681e |
+static char *
|
|
|
d1681e |
getChoices (const char *value)
|
|
|
d1681e |
{
|
|
|
d1681e |
int i = 0;
|
|
|
d1681e |
@@ -428,6 +446,74 @@ out:
|
|
|
d1681e |
return;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+/* Code to save hashed subvol on inode ctx as a mds subvol
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_inode_ctx_mdsvol_set (inode_t *inode, xlator_t *this, xlator_t *mds_subvol)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ uint64_t ctx_int = 0;
|
|
|
d1681e |
+ gf_boolean_t ctx_free = _gf_false;
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&inode->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ ret = __inode_ctx_get (inode, this , &ctx_int);
|
|
|
d1681e |
+ if (ctx_int) {
|
|
|
d1681e |
+ ctx = (dht_inode_ctx_t *)ctx_int;
|
|
|
d1681e |
+ ctx->mds_subvol = mds_subvol;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ ctx = GF_CALLOC (1, sizeof(*ctx), gf_dht_mt_inode_ctx_t);
|
|
|
d1681e |
+ if (!ctx)
|
|
|
d1681e |
+ goto unlock;
|
|
|
d1681e |
+ ctx->mds_subvol = mds_subvol;
|
|
|
d1681e |
+ ctx_free = _gf_true;
|
|
|
d1681e |
+ ctx_int = (long) ctx;
|
|
|
d1681e |
+ ret = __inode_ctx_set (inode, this, &ctx_int);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+unlock:
|
|
|
d1681e |
+ UNLOCK (&inode->lock);
|
|
|
d1681e |
+ if (ret && ctx_free)
|
|
|
d1681e |
+ GF_FREE (ctx);
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+/*Code to get mds subvol from inode ctx */
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_inode_ctx_mdsvol_get (inode_t *inode, xlator_t *this, xlator_t **mdsvol)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_inode_ctx_t *ctx = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!mdsvol)
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (__is_root_gfid(inode->gfid)) {
|
|
|
d1681e |
+ (*mdsvol) = FIRST_CHILD (this);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = dht_inode_ctx_get (inode, this, &ctx;;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!ret && ctx) {
|
|
|
d1681e |
+ if (ctx->mds_subvol) {
|
|
|
d1681e |
+ *mdsvol = ctx->mds_subvol;
|
|
|
d1681e |
+ ret = 0;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
/* TODO:
|
|
|
d1681e |
- use volumename in xattr instead of "dht"
|
|
|
d1681e |
- use NS locks
|
|
|
d1681e |
@@ -443,6 +529,7 @@ dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
{
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
dht_layout_t *layout = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
int ret = -1;
|
|
|
d1681e |
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", frame, out);
|
|
|
d1681e |
@@ -450,6 +537,7 @@ dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
|
|
|
d1681e |
|
|
|
d1681e |
local = frame->local;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
ret = op_ret;
|
|
|
d1681e |
|
|
|
d1681e |
FRAME_SU_UNDO (frame, dht_local_t);
|
|
|
d1681e |
@@ -467,6 +555,8 @@ dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
|
|
|
d1681e |
DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
|
|
|
d1681e |
dht_set_fixed_dir_stat (&local->postparent);
|
|
|
d1681e |
+ /* Delete mds xattr at the time of STACK UNWIND */
|
|
|
d1681e |
+ GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr);
|
|
|
d1681e |
|
|
|
d1681e |
DHT_STACK_UNWIND (lookup, frame, ret, local->op_errno, local->inode,
|
|
|
d1681e |
&local->stbuf, local->xattr, &local->postparent);
|
|
|
d1681e |
@@ -492,10 +582,12 @@ dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
|
|
|
d1681e |
int i = 0;
|
|
|
d1681e |
loc_t loc = {0 };
|
|
|
d1681e |
int8_t is_read_only = 0, layout_anomalies = 0;
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
local = discover_frame->local;
|
|
|
d1681e |
layout = local->layout;
|
|
|
d1681e |
conf = this->private;
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
|
|
|
d1681e |
LOCK(&discover_frame->lock);
|
|
|
d1681e |
{
|
|
|
d1681e |
@@ -507,6 +599,18 @@ dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
|
|
|
d1681e |
if (!main_frame)
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
|
|
|
d1681e |
+ /* Code to update all extended attributed from
|
|
|
d1681e |
+ subvol to local->xattr on that internal xattr has found
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (conf->subvolume_cnt == 1)
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+ if (local->need_xattr_heal && (local->mds_xattr)) {
|
|
|
d1681e |
+ dht_dir_set_heal_xattr (this, local, local->xattr,
|
|
|
d1681e |
+ local->mds_xattr, NULL, NULL);
|
|
|
d1681e |
+ dict_unref (local->mds_xattr);
|
|
|
d1681e |
+ local->mds_xattr = NULL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
ret = dict_get_int8 (local->xattr_req, QUOTA_READ_ONLY_KEY,
|
|
|
d1681e |
&is_read_only);
|
|
|
d1681e |
if (ret < 0)
|
|
|
d1681e |
@@ -575,6 +679,26 @@ dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+ if (IA_ISDIR (local->stbuf.ia_type)) {
|
|
|
d1681e |
+ /* Call function to save hashed subvol on inode ctx if
|
|
|
d1681e |
+ internal mds xattr is not present and all subvols are up
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (!local->op_ret && !__is_root_gfid (local->stbuf.ia_gfid))
|
|
|
d1681e |
+ (void) dht_mark_mds_subvolume (discover_frame, this);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->need_xattr_heal && !heal_path) {
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+ ret = dht_dir_xattr_heal (this, local);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR,
|
|
|
d1681e |
+ ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "xattr heal failed for "
|
|
|
d1681e |
+ "directory gfid is %s ",
|
|
|
d1681e |
+ gfid_local);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
if (source && (heal_path || layout_anomalies)) {
|
|
|
d1681e |
gf_uuid_copy (loc.gfid, local->gfid);
|
|
|
d1681e |
if (gf_uuid_is_null (loc.gfid)) {
|
|
|
d1681e |
@@ -621,10 +745,14 @@ cleanup:
|
|
|
d1681e |
}
|
|
|
d1681e |
done:
|
|
|
d1681e |
dht_set_fixed_dir_stat (&local->postparent);
|
|
|
d1681e |
+ /* Delete mds xattr at the time of STACK UNWIND */
|
|
|
d1681e |
+ GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr);
|
|
|
d1681e |
+
|
|
|
d1681e |
DHT_STACK_UNWIND (lookup, main_frame, local->op_ret, local->op_errno,
|
|
|
d1681e |
local->inode, &local->stbuf, local->xattr,
|
|
|
d1681e |
&local->postparent);
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
out:
|
|
|
d1681e |
DHT_STACK_UNWIND (lookup, main_frame, -1, op_errno, NULL, NULL, NULL,
|
|
|
d1681e |
NULL);
|
|
|
d1681e |
@@ -633,6 +761,170 @@ out:
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
+dht_mds_internal_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *hashed_subvol = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+ int ret = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ hashed_subvol = cookie;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (op_ret) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_ret,
|
|
|
d1681e |
+ "Failed to set %s on the MDS for path %s. ",
|
|
|
d1681e |
+ conf->mds_xattr_key, local->loc.path);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ /* Save mds subvol on inode ctx */
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_set (local->inode, this,
|
|
|
d1681e |
+ hashed_subvol);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_SET_INODE_CTX_FAILED,
|
|
|
d1681e |
+ "Failed to set mds subvol on inode ctx"
|
|
|
d1681e |
+ " %s for %s", hashed_subvol->name,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ DHT_STACK_DESTROY (frame);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Code to save hashed subvol on inode ctx only while no
|
|
|
d1681e |
+ mds xattr is availble and all subvols are up for fresh
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_mark_mds_subvolume (call_frame_t *frame, xlator_t *this)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *hashed_subvol = NULL;
|
|
|
d1681e |
+ int i = 0;
|
|
|
d1681e |
+ gf_boolean_t vol_down = _gf_false;
|
|
|
d1681e |
+ dht_conf_t *conf = 0;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ dict_t *xattrs = NULL;
|
|
|
d1681e |
+ dht_local_t *copy_local = NULL;
|
|
|
d1681e |
+ call_frame_t *xattr_frame = NULL;
|
|
|
d1681e |
+ int32_t zero[1] = {0};
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO ("dht", frame, out);
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO ("dht", this, out);
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Code to update hashed subvol consider as a mds subvol
|
|
|
d1681e |
+ and save on inode ctx if all subvols are up and no internal
|
|
|
d1681e |
+ xattr has been set yet
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (!dict_get (local->xattr, conf->mds_xattr_key)) {
|
|
|
d1681e |
+ /* It means no internal MDS xattr has been set yet
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ /* Check the status of all subvol are up
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ if (!conf->subvolume_status[i]) {
|
|
|
d1681e |
+ vol_down = _gf_true;
|
|
|
d1681e |
+ break;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (vol_down) {
|
|
|
d1681e |
+ ret = 0;
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "subvol %s is down. Unable to "
|
|
|
d1681e |
+ " save mds subvol on inode for "
|
|
|
d1681e |
+ " path %s gfid is %s " ,
|
|
|
d1681e |
+ conf->subvolumes[i]->name, local->loc.path,
|
|
|
d1681e |
+ gfid_local);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* Calculate hashed subvol based on inode and
|
|
|
d1681e |
+ parent inode
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ hashed_subvol = dht_inode_get_hashed_subvol (local->inode,
|
|
|
d1681e |
+ this, &local->loc);
|
|
|
d1681e |
+ if (!hashed_subvol) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_DEBUG, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "Failed to get hashed subvol for path %s"
|
|
|
d1681e |
+ " gfid is %s ",
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ xattrs = dict_new ();
|
|
|
d1681e |
+ if (!xattrs) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_NO_MEMORY, "dict_new failed");
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* Add internal MDS xattr on disk for hashed subvol
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ ret = dht_dict_set_array (xattrs, conf->mds_xattr_key, zero, 1);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary"
|
|
|
d1681e |
+ " value:key = %s for "
|
|
|
d1681e |
+ "path %s", conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ xattr_frame = create_frame (this, this->ctx->pool);
|
|
|
d1681e |
+ if (!xattr_frame) {
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ copy_local = dht_local_init (xattr_frame, &(local->loc),
|
|
|
d1681e |
+ NULL, 0);
|
|
|
d1681e |
+ if (!copy_local) {
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ DHT_STACK_DESTROY (xattr_frame);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ copy_local->stbuf = local->stbuf;
|
|
|
d1681e |
+ if (!copy_local->inode)
|
|
|
d1681e |
+ copy_local->inode = inode_ref (local->inode);
|
|
|
d1681e |
+ gf_uuid_copy (copy_local->loc.gfid, local->gfid);
|
|
|
d1681e |
+ STACK_WIND_COOKIE (xattr_frame, dht_mds_internal_setxattr_cbk,
|
|
|
d1681e |
+ hashed_subvol, hashed_subvol,
|
|
|
d1681e |
+ hashed_subvol->fops->setxattr,
|
|
|
d1681e |
+ &local->loc, xattrs, 0, NULL);
|
|
|
d1681e |
+ ret = 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ ret = 0;
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "internal xattr %s is present on subvol"
|
|
|
d1681e |
+ "on path %s gfid is %s " , conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (xattrs)
|
|
|
d1681e |
+ dict_unref (xattrs);
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
int op_ret, int op_errno,
|
|
|
d1681e |
inode_t *inode, struct iatt *stbuf, dict_t *xattr,
|
|
|
d1681e |
@@ -644,11 +936,15 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
dht_layout_t *layout = NULL;
|
|
|
d1681e |
int ret = -1;
|
|
|
d1681e |
int is_dir = 0;
|
|
|
d1681e |
+ int32_t check_mds = 0;
|
|
|
d1681e |
int is_linkfile = 0;
|
|
|
d1681e |
int attempt_unwind = 0;
|
|
|
d1681e |
dht_conf_t *conf = 0;
|
|
|
d1681e |
- char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
- char gfid_node[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ char gfid_node[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ int32_t mds_xattr_val[1] = {0};
|
|
|
d1681e |
+ int errst = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", frame, out);
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", this, out);
|
|
|
d1681e |
@@ -743,6 +1039,41 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
dht_iatt_merge (this, &local->stbuf, stbuf, prev);
|
|
|
d1681e |
dht_iatt_merge (this, &local->postparent, postparent,
|
|
|
d1681e |
prev);
|
|
|
d1681e |
+ if (!dict_get (xattr, conf->mds_xattr_key)) {
|
|
|
d1681e |
+ goto unlock;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "internal xattr %s is present on subvol"
|
|
|
d1681e |
+ "on path %s gfid is %s " ,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key,
|
|
|
d1681e |
+ mds_xattr_val, 1, &errst);
|
|
|
d1681e |
+ /* save mds subvol on inode ctx */
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_set (local->inode, this,
|
|
|
d1681e |
+ prev);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_SET_INODE_CTX_FAILED,
|
|
|
d1681e |
+ "Failed to set hashed subvol for %s vol is %s",
|
|
|
d1681e |
+ local->loc.path, prev->name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if ((check_mds < 0) && !errst) {
|
|
|
d1681e |
+ local->mds_xattr = dict_ref (xattr);
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "Value of %s is not zero on mds subvol"
|
|
|
d1681e |
+ "so xattr needs to be healed on non mds"
|
|
|
d1681e |
+ " path is %s and vol name is %s "
|
|
|
d1681e |
+ " gfid is %s" ,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path,
|
|
|
d1681e |
+ prev->name, gfid_local);
|
|
|
d1681e |
+ local->need_xattr_heal = 1;
|
|
|
d1681e |
+ local->mds_subvol = prev;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
}
|
|
|
d1681e |
unlock:
|
|
|
d1681e |
UNLOCK (&frame->lock);
|
|
|
d1681e |
@@ -841,6 +1172,99 @@ err:
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+/* Get the value of key from dict in the bytewise and save in array after
|
|
|
d1681e |
+ convert from network byte order to host byte order
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int32_t
|
|
|
d1681e |
+dht_dict_get_array (dict_t *dict, char *key, int32_t value[], int32_t size, int *errst)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ void *ptr = NULL;
|
|
|
d1681e |
+ int32_t len = -1;
|
|
|
d1681e |
+ int32_t vindex = -1;
|
|
|
d1681e |
+ int32_t err = -1;
|
|
|
d1681e |
+ int ret = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (dict == NULL) {
|
|
|
d1681e |
+ (*errst) = -1;
|
|
|
d1681e |
+ return -EINVAL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ err = dict_get_ptr_and_len(dict, key, &ptr, &len;;
|
|
|
d1681e |
+ if (err != 0) {
|
|
|
d1681e |
+ (*errst) = -1;
|
|
|
d1681e |
+ return err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (len != (size * sizeof (int32_t))) {
|
|
|
d1681e |
+ (*errst) = -1;
|
|
|
d1681e |
+ return -EINVAL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ memset (value, 0, size * sizeof(int32_t));
|
|
|
d1681e |
+ for (vindex = 0; vindex < size; vindex++) {
|
|
|
d1681e |
+ value[vindex] = ntoh32(*((int32_t *)ptr + vindex));
|
|
|
d1681e |
+ if (value[vindex] < 0)
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Code to call syntask to heal custom xattr from hashed subvol
|
|
|
d1681e |
+ to non hashed subvol
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_dir_xattr_heal (xlator_t *this, dht_local_t *local)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *copy_local = NULL;
|
|
|
d1681e |
+ call_frame_t *copy = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->gfid) {
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "No gfid exists for path %s "
|
|
|
d1681e |
+ "so healing xattr is not possible",
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ copy = create_frame (this, this->ctx->pool);
|
|
|
d1681e |
+ if (copy) {
|
|
|
d1681e |
+ copy_local = dht_local_init (copy, &(local->loc), NULL, 0);
|
|
|
d1681e |
+ if (!copy_local) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "Memory allocation failed "
|
|
|
d1681e |
+ "for path %s gfid %s ",
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ DHT_STACK_DESTROY (copy);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ copy_local->stbuf = local->stbuf;
|
|
|
d1681e |
+ gf_uuid_copy (copy_local->loc.gfid, local->gfid);
|
|
|
d1681e |
+ copy_local->mds_subvol = local->mds_subvol;
|
|
|
d1681e |
+ FRAME_SU_DO (copy, dht_local_t);
|
|
|
d1681e |
+ ret = synctask_new (this->ctx->env, dht_dir_heal_xattrs,
|
|
|
d1681e |
+ dht_dir_heal_xattrs_done,
|
|
|
d1681e |
+ copy, copy);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "Synctask creation failed to heal xattr "
|
|
|
d1681e |
+ "for path %s gfid %s ",
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ DHT_STACK_DESTROY (copy);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
@@ -849,13 +1273,17 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
struct iatt *postparent)
|
|
|
d1681e |
{
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
int this_call_cnt = 0;
|
|
|
d1681e |
xlator_t *prev = NULL;
|
|
|
d1681e |
dht_layout_t *layout = NULL;
|
|
|
d1681e |
int ret = -1;
|
|
|
d1681e |
int is_dir = 0;
|
|
|
d1681e |
- char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
- char gfid_node[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ int32_t check_mds = 0;
|
|
|
d1681e |
+ int errst = 0;
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ char gfid_node[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ int32_t mds_xattr_val[1] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", frame, out);
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", this, out);
|
|
|
d1681e |
@@ -865,17 +1293,20 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
|
|
|
d1681e |
local = frame->local;
|
|
|
d1681e |
prev = cookie;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
|
|
|
d1681e |
layout = local->layout;
|
|
|
d1681e |
|
|
|
d1681e |
- if (!op_ret && gf_uuid_is_null (local->gfid))
|
|
|
d1681e |
+ if (!op_ret && gf_uuid_is_null (local->gfid)) {
|
|
|
d1681e |
memcpy (local->gfid, stbuf->ia_gfid, 16);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (local->gfid)
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
|
|
|
d1681e |
/* Check if the gfid is different for file from other node */
|
|
|
d1681e |
if (!op_ret && gf_uuid_compare (local->gfid, stbuf->ia_gfid)) {
|
|
|
d1681e |
|
|
|
d1681e |
gf_uuid_unparse(stbuf->ia_gfid, gfid_node);
|
|
|
d1681e |
- gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
|
|
|
d1681e |
gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
DHT_MSG_GFID_MISMATCH,
|
|
|
d1681e |
@@ -930,6 +1361,41 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
|
|
|
d1681e |
dht_iatt_merge (this, &local->stbuf, stbuf, prev);
|
|
|
d1681e |
dht_iatt_merge (this, &local->postparent, postparent, prev);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!dict_get (xattr, conf->mds_xattr_key)) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "Internal xattr %s is not present "
|
|
|
d1681e |
+ " on path %s gfid is %s " ,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ goto unlock;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ /* Save mds subvol on inode ctx */
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_set (local->inode, this,
|
|
|
d1681e |
+ prev);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_SET_INODE_CTX_FAILED,
|
|
|
d1681e |
+ "Failed to set hashed subvol for %s vol is %s",
|
|
|
d1681e |
+ local->loc.path, prev->name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key,
|
|
|
d1681e |
+ mds_xattr_val, 1, &errst);
|
|
|
d1681e |
+ if ((check_mds < 0) && !errst) {
|
|
|
d1681e |
+ local->mds_xattr = dict_ref (xattr);
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "Value of %s is not zero on hashed subvol "
|
|
|
d1681e |
+ "so xattr needs to be heal on non hashed"
|
|
|
d1681e |
+ " path is %s and vol name is %s "
|
|
|
d1681e |
+ " gfid is %s" ,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path,
|
|
|
d1681e |
+ prev->name, gfid_local);
|
|
|
d1681e |
+ local->need_xattr_heal = 1;
|
|
|
d1681e |
+ local->mds_subvol = prev;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
}
|
|
|
d1681e |
unlock:
|
|
|
d1681e |
UNLOCK (&frame->lock);
|
|
|
d1681e |
@@ -938,7 +1404,20 @@ unlock:
|
|
|
d1681e |
this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
|
|
|
d1681e |
if (is_last_call (this_call_cnt)) {
|
|
|
d1681e |
- gf_uuid_copy (local->loc.gfid, local->gfid);
|
|
|
d1681e |
+ /* No need to call xattr heal code if volume count is 1
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (conf->subvolume_cnt == 1)
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Code to update all extended attributed from hashed subvol
|
|
|
d1681e |
+ to local->xattr
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (local->need_xattr_heal && (local->mds_xattr)) {
|
|
|
d1681e |
+ dht_dir_set_heal_xattr (this, local, local->xattr,
|
|
|
d1681e |
+ local->mds_xattr, NULL, NULL);
|
|
|
d1681e |
+ dict_unref (local->mds_xattr);
|
|
|
d1681e |
+ local->mds_xattr = NULL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
|
|
|
d1681e |
if (local->need_selfheal) {
|
|
|
d1681e |
local->need_selfheal = 0;
|
|
|
d1681e |
@@ -957,6 +1436,9 @@ unlock:
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
dht_layout_set (this, local->inode, layout);
|
|
|
d1681e |
+ if (!dict_get (local->xattr, conf->mds_xattr_key) ||
|
|
|
d1681e |
+ local->need_xattr_heal)
|
|
|
d1681e |
+ goto selfheal;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
if (local->inode) {
|
|
|
d1681e |
@@ -971,6 +1453,8 @@ unlock:
|
|
|
d1681e |
|
|
|
d1681e |
DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
|
|
|
d1681e |
dht_set_fixed_dir_stat (&local->postparent);
|
|
|
d1681e |
+ /* Delete mds xattr at the time of STACK UNWIND */
|
|
|
d1681e |
+ GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr);
|
|
|
d1681e |
DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
|
|
|
d1681e |
local->inode, &local->stbuf, local->xattr,
|
|
|
d1681e |
&local->postparent);
|
|
|
d1681e |
@@ -1027,6 +1511,9 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
char gfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
uint32_t vol_commit_hash = 0;
|
|
|
d1681e |
xlator_t *subvol = NULL;
|
|
|
d1681e |
+ int32_t check_mds = 0;
|
|
|
d1681e |
+ int errst = 0;
|
|
|
d1681e |
+ int32_t mds_xattr_val[1] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", frame, err);
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", this, err);
|
|
|
d1681e |
@@ -1051,6 +1538,9 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
|
|
|
d1681e |
LOCK (&frame->lock);
|
|
|
d1681e |
{
|
|
|
d1681e |
+ if (gf_uuid_is_null (local->gfid)) {
|
|
|
d1681e |
+ memcpy (local->gfid, local->loc.gfid, 16);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
|
|
|
d1681e |
gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
"revalidate lookup of %s "
|
|
|
d1681e |
@@ -1136,6 +1626,7 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
local->prebuf.ia_prot = stbuf->ia_prot;
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
+
|
|
|
d1681e |
if (local->stbuf.ia_type != IA_INVAL)
|
|
|
d1681e |
{
|
|
|
d1681e |
if ((local->stbuf.ia_gid != stbuf->ia_gid) ||
|
|
|
d1681e |
@@ -1146,6 +1637,44 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
local->need_selfheal = 1;
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
+ if (!dict_get (xattr, conf->mds_xattr_key)) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "internal xattr %s is not present"
|
|
|
d1681e |
+ " on path %s gfid is %s " ,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path, gfid);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key,
|
|
|
d1681e |
+ mds_xattr_val, 1, &errst);
|
|
|
d1681e |
+ if (local->mds_subvol == prev) {
|
|
|
d1681e |
+ local->mds_stbuf.ia_gid = stbuf->ia_gid;
|
|
|
d1681e |
+ local->mds_stbuf.ia_uid = stbuf->ia_uid;
|
|
|
d1681e |
+ local->mds_stbuf.ia_prot = stbuf->ia_prot;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* save mds subvol on inode ctx */
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_set (local->inode, this,
|
|
|
d1681e |
+ prev);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_SET_INODE_CTX_FAILED,
|
|
|
d1681e |
+ "Failed to set MDS subvol for %s vol is %s",
|
|
|
d1681e |
+ local->loc.path, prev->name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if ((check_mds < 0) && !errst) {
|
|
|
d1681e |
+ local->mds_xattr = dict_ref (xattr);
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "Value of %s is not zero on "
|
|
|
d1681e |
+ "hashed subvol so xattr needs to"
|
|
|
d1681e |
+ " be healed on non hashed"
|
|
|
d1681e |
+ " path is %s and vol name is %s "
|
|
|
d1681e |
+ " gfid is %s" ,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path,
|
|
|
d1681e |
+ prev->name, gfid);
|
|
|
d1681e |
+ local->need_xattr_heal = 1;
|
|
|
d1681e |
+ local->mds_subvol = prev;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
ret = dht_layout_dir_mismatch (this, layout,
|
|
|
d1681e |
prev, &local->loc,
|
|
|
d1681e |
xattr);
|
|
|
d1681e |
@@ -1215,13 +1744,52 @@ out:
|
|
|
d1681e |
&& (conf && conf->unhashed_sticky_bit)) {
|
|
|
d1681e |
local->stbuf.ia_prot.sticky = 1;
|
|
|
d1681e |
}
|
|
|
d1681e |
+ /* No need to call heal code if volume count is 1
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (conf->subvolume_cnt == 1)
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Code to update all extended attributed from hashed subvol
|
|
|
d1681e |
+ to local->xattr
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (local->need_xattr_heal && (local->mds_xattr)) {
|
|
|
d1681e |
+ dht_dir_set_heal_xattr (this, local, local->xattr,
|
|
|
d1681e |
+ local->mds_xattr, NULL, NULL);
|
|
|
d1681e |
+ dict_unref (local->mds_xattr);
|
|
|
d1681e |
+ local->mds_xattr = NULL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* Call function to save hashed subvol on inode ctx if
|
|
|
d1681e |
+ internal mds xattr is not present and all subvols are up
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (inode && !__is_root_gfid (inode->gfid) &&
|
|
|
d1681e |
+ (!local->op_ret) && (IA_ISDIR (local->stbuf.ia_type)))
|
|
|
d1681e |
+ (void) dht_mark_mds_subvolume (frame, this);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->need_xattr_heal) {
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+ ret = dht_dir_xattr_heal (this, local);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR,
|
|
|
d1681e |
+ ret, DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "xattr heal failed for directory %s "
|
|
|
d1681e |
+ " gfid %s ", local->loc.path,
|
|
|
d1681e |
+ gfid);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
if (local->need_selfheal) {
|
|
|
d1681e |
local->need_selfheal = 0;
|
|
|
d1681e |
- gf_uuid_copy (local->gfid, local->stbuf.ia_gfid);
|
|
|
d1681e |
- local->stbuf.ia_gid = local->prebuf.ia_gid;
|
|
|
d1681e |
- local->stbuf.ia_uid = local->prebuf.ia_uid;
|
|
|
d1681e |
- if (__is_root_gfid(local->stbuf.ia_gfid))
|
|
|
d1681e |
+ if (!__is_root_gfid (inode->gfid)) {
|
|
|
d1681e |
+ gf_uuid_copy (local->gfid, local->mds_stbuf.ia_gfid);
|
|
|
d1681e |
+ if (local->mds_stbuf.ia_gid || local->mds_stbuf.ia_uid) {
|
|
|
d1681e |
+ local->stbuf.ia_gid = local->mds_stbuf.ia_gid;
|
|
|
d1681e |
+ local->stbuf.ia_uid = local->mds_stbuf.ia_uid;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ gf_uuid_copy (local->gfid, local->stbuf.ia_gfid);
|
|
|
d1681e |
+ local->stbuf.ia_gid = local->prebuf.ia_gid;
|
|
|
d1681e |
+ local->stbuf.ia_uid = local->prebuf.ia_uid;
|
|
|
d1681e |
local->stbuf.ia_prot = local->prebuf.ia_prot;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
copy = create_frame (this, this->ctx->pool);
|
|
|
d1681e |
if (copy) {
|
|
|
d1681e |
copy_local = dht_local_init (copy, &local->loc,
|
|
|
d1681e |
@@ -1229,6 +1797,8 @@ out:
|
|
|
d1681e |
if (!copy_local)
|
|
|
d1681e |
goto cont;
|
|
|
d1681e |
copy_local->stbuf = local->stbuf;
|
|
|
d1681e |
+ copy_local->mds_stbuf = local->mds_stbuf;
|
|
|
d1681e |
+ copy_local->mds_subvol = local->mds_subvol;
|
|
|
d1681e |
copy->local = copy_local;
|
|
|
d1681e |
FRAME_SU_DO (copy, dht_local_t);
|
|
|
d1681e |
ret = synctask_new (this->ctx->env,
|
|
|
d1681e |
@@ -1283,6 +1853,8 @@ cont:
|
|
|
d1681e |
local->op_ret = -1;
|
|
|
d1681e |
local->op_errno = ESTALE;
|
|
|
d1681e |
}
|
|
|
d1681e |
+ /* Delete mds xattr at the time of STACK UNWIND */
|
|
|
d1681e |
+ GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr);
|
|
|
d1681e |
|
|
|
d1681e |
DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
|
|
|
d1681e |
local->inode, &local->stbuf, local->xattr,
|
|
|
d1681e |
@@ -2303,6 +2875,62 @@ out:
|
|
|
d1681e |
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+/* Code to get hashed subvol based on inode and loc
|
|
|
d1681e |
+ First it check if loc->parent and loc->path exist then it get
|
|
|
d1681e |
+ hashed subvol based on loc.
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+
|
|
|
d1681e |
+xlator_t *
|
|
|
d1681e |
+dht_inode_get_hashed_subvol (inode_t *inode, xlator_t *this, loc_t *loc)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ char *path = NULL;
|
|
|
d1681e |
+ loc_t populate_loc = {0, };
|
|
|
d1681e |
+ char *name = NULL;
|
|
|
d1681e |
+ xlator_t *hash_subvol = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!inode)
|
|
|
d1681e |
+ return hash_subvol;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (loc && loc->parent && loc->path) {
|
|
|
d1681e |
+ if (!loc->name) {
|
|
|
d1681e |
+ name = strrchr (loc->path, '/');
|
|
|
d1681e |
+ if (name) {
|
|
|
d1681e |
+ loc->name = name + 1;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ hash_subvol = dht_subvol_get_hashed (this, loc);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!gf_uuid_is_null (inode->gfid)) {
|
|
|
d1681e |
+ populate_loc.inode = inode_ref (inode);
|
|
|
d1681e |
+ populate_loc.parent = inode_parent (populate_loc.inode,
|
|
|
d1681e |
+ NULL, NULL);
|
|
|
d1681e |
+ inode_path (populate_loc.inode, NULL, &path);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!path)
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ populate_loc.path = path;
|
|
|
d1681e |
+ if (!populate_loc.name && populate_loc.path) {
|
|
|
d1681e |
+ name = strrchr (populate_loc.path, '/');
|
|
|
d1681e |
+ if (name) {
|
|
|
d1681e |
+ populate_loc.name = name + 1;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ hash_subvol = dht_subvol_get_hashed (this, &populate_loc);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (populate_loc.inode)
|
|
|
d1681e |
+ loc_wipe (&populate_loc);
|
|
|
d1681e |
+ return hash_subvol;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
@@ -2537,6 +3165,7 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
{
|
|
|
d1681e |
xlator_t *subvol = NULL;
|
|
|
d1681e |
xlator_t *hashed_subvol = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
dht_conf_t *conf = NULL;
|
|
|
d1681e |
int ret = -1;
|
|
|
d1681e |
@@ -2587,6 +3216,15 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
local->xattr_req = dict_new ();
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+ ret = dict_set_uint32 (local->xattr_req, conf->mds_xattr_key, 4);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value:key = %s for "
|
|
|
d1681e |
+ "path %s", conf->mds_xattr_key, loc->path);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
/* Nameless lookup */
|
|
|
d1681e |
|
|
|
d1681e |
if (gf_uuid_is_null (loc->pargfid) && !gf_uuid_is_null (loc->gfid) &&
|
|
|
d1681e |
@@ -2663,6 +3301,14 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
goto err;
|
|
|
d1681e |
}
|
|
|
d1681e |
if (IA_ISDIR (local->inode->ia_type)) {
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_get (local->inode, this,
|
|
|
d1681e |
+ &mds_subvol);
|
|
|
d1681e |
+ if (ret || !mds_subvol) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "Failed to get mds subvol for path %s",
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ local->mds_subvol = mds_subvol;
|
|
|
d1681e |
local->call_cnt = call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
STACK_WIND_COOKIE (frame, dht_revalidate_cbk,
|
|
|
d1681e |
@@ -2851,76 +3497,300 @@ dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
|
|
|
d1681e |
local->op_ret = 0;
|
|
|
d1681e |
|
|
|
d1681e |
- local->postparent = *postparent;
|
|
|
d1681e |
- local->preparent = *preparent;
|
|
|
d1681e |
+ local->postparent = *postparent;
|
|
|
d1681e |
+ local->preparent = *preparent;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->loc.parent) {
|
|
|
d1681e |
+ dht_inode_ctx_time_update (local->loc.parent, this,
|
|
|
d1681e |
+ &local->preparent, 0);
|
|
|
d1681e |
+ dht_inode_ctx_time_update (local->loc.parent, this,
|
|
|
d1681e |
+ &local->postparent, 1);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+unlock:
|
|
|
d1681e |
+ UNLOCK (&frame->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!local->op_ret) {
|
|
|
d1681e |
+ hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
|
|
|
d1681e |
+ if (hashed_subvol && hashed_subvol != local->cached_subvol) {
|
|
|
d1681e |
+ /*
|
|
|
d1681e |
+ * If hashed and cached are different, then we need
|
|
|
d1681e |
+ * to unlink linkfile from hashed subvol if data
|
|
|
d1681e |
+ * file is deleted successfully
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, dht_unlink_linkfile_cbk,
|
|
|
d1681e |
+ hashed_subvol, hashed_subvol,
|
|
|
d1681e |
+ hashed_subvol->fops->unlink,
|
|
|
d1681e |
+ &local->loc, local->flags, xdata);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ dht_set_fixed_dir_stat (&local->preparent);
|
|
|
d1681e |
+ dht_set_fixed_dir_stat (&local->postparent);
|
|
|
d1681e |
+ DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
|
|
|
d1681e |
+ &local->preparent, &local->postparent, xdata);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+static int
|
|
|
d1681e |
+dht_common_setxattr_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
|
|
|
d1681e |
+ dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ int this_call_cnt = 0;
|
|
|
d1681e |
+ xlator_t *prev = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ prev = cookie;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&frame->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ if (op_ret == -1) {
|
|
|
d1681e |
+ local->op_errno = op_errno;
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
+ "subvolume %s returned -1",
|
|
|
d1681e |
+ prev->name);
|
|
|
d1681e |
+ goto unlock;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->op_ret = 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+unlock:
|
|
|
d1681e |
+ UNLOCK (&frame->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
+ if (is_last_call (this_call_cnt)) {
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setxattr, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, NULL);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Set the value[] of key into dict after convert from
|
|
|
d1681e |
+ host byte order to network byte order
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int32_t dht_dict_set_array (dict_t *dict, char *key, int32_t value[],
|
|
|
d1681e |
+ int32_t size)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ int32_t *ptr = NULL;
|
|
|
d1681e |
+ int32_t vindex;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (value == NULL) {
|
|
|
d1681e |
+ return -EINVAL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ptr = GF_MALLOC(sizeof(int32_t) * size, gf_common_mt_char);
|
|
|
d1681e |
+ if (ptr == NULL) {
|
|
|
d1681e |
+ return -ENOMEM;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ for (vindex = 0; vindex < size; vindex++) {
|
|
|
d1681e |
+ ptr[vindex] = hton32(value[vindex]);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ ret = dict_set_bin(dict, key, ptr, sizeof(int32_t) * size);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ GF_FREE (ptr);
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Code to wind a xattrop call to add 1 on current mds internal xattr
|
|
|
d1681e |
+ value
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_setxattr_non_mds_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ int this_call_cnt = 0;
|
|
|
d1681e |
+ int ret = 0;
|
|
|
d1681e |
+ dict_t *xattrop = NULL;
|
|
|
d1681e |
+ int32_t addone[1] = {1};
|
|
|
d1681e |
+ call_frame_t *prev = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ prev = cookie;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&frame->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ if (op_ret && !local->op_ret) {
|
|
|
d1681e |
+ local->op_ret = op_ret;
|
|
|
d1681e |
+ local->op_errno = op_errno;
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
+ "subvolume %s returned -1",
|
|
|
d1681e |
+ prev->this->name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ UNLOCK (&frame->lock);
|
|
|
d1681e |
+ this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (is_last_call (this_call_cnt)) {
|
|
|
d1681e |
+ if (!local->op_ret) {
|
|
|
d1681e |
+ xattrop = dict_new ();
|
|
|
d1681e |
+ if (!xattrop) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR,
|
|
|
d1681e |
+ DHT_MSG_NO_MEMORY, 0,
|
|
|
d1681e |
+ "dictionary creation failed");
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ ret = dht_dict_set_array (xattrop,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ addone, 1);
|
|
|
d1681e |
+ if (ret != 0) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "dictionary set array failed ");
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR) {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_common_xattrop_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->xattrop,
|
|
|
d1681e |
+ &local->loc, GF_XATTROP_ADD_ARRAY,
|
|
|
d1681e |
+ xattrop, NULL);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_common_xattrop_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->fxattrop,
|
|
|
d1681e |
+ local->fd, GF_XATTROP_ADD_ARRAY,
|
|
|
d1681e |
+ xattrop, NULL);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR)
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setxattr, frame, 0, 0, local->xdata);
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ DHT_STACK_UNWIND (fsetxattr, frame, 0, 0, local->xdata);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (xattrop)
|
|
|
d1681e |
+ dict_unref (xattrop);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR)
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setxattr, frame, 0, 0, local->xdata);
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ DHT_STACK_UNWIND (fsetxattr, frame, 0, 0, local->xdata);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_setxattr_mds_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+ call_frame_t *prev = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ int i = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ prev = cookie;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ mds_subvol = local->mds_subvol;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (op_ret == -1) {
|
|
|
d1681e |
+ local->op_ret = op_ret;
|
|
|
d1681e |
+ local->op_errno = op_errno;
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
+ "subvolume %s returned -1",
|
|
|
d1681e |
+ prev->this->name);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->op_ret = 0;
|
|
|
d1681e |
+ local->call_cnt = conf->subvolume_cnt - 1;
|
|
|
d1681e |
+ local->xdata = dict_ref (xdata);
|
|
|
d1681e |
|
|
|
d1681e |
- if (local->loc.parent) {
|
|
|
d1681e |
- dht_inode_ctx_time_update (local->loc.parent, this,
|
|
|
d1681e |
- &local->preparent, 0);
|
|
|
d1681e |
- dht_inode_ctx_time_update (local->loc.parent, this,
|
|
|
d1681e |
- &local->postparent, 1);
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ if (mds_subvol && (mds_subvol == conf->subvolumes[i]))
|
|
|
d1681e |
+ continue;
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR) {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_setxattr_non_mds_cbk,
|
|
|
d1681e |
+ conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i]->fops->setxattr,
|
|
|
d1681e |
+ &local->loc, local->xattr,
|
|
|
d1681e |
+ local->flags, local->xattr_req);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_setxattr_non_mds_cbk,
|
|
|
d1681e |
+ conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i]->fops->fsetxattr,
|
|
|
d1681e |
+ local->fd, local->xattr,
|
|
|
d1681e |
+ local->flags, local->xattr_req);
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
-unlock:
|
|
|
d1681e |
- UNLOCK (&frame->lock);
|
|
|
d1681e |
|
|
|
d1681e |
- if (!local->op_ret) {
|
|
|
d1681e |
- hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
|
|
|
d1681e |
- if (hashed_subvol &&
|
|
|
d1681e |
- hashed_subvol != local->cached_subvol) {
|
|
|
d1681e |
- /*
|
|
|
d1681e |
- * If hashed and cached are different, then we need
|
|
|
d1681e |
- * to unlink linkfile from hashed subvol if data
|
|
|
d1681e |
- * file is deleted successfully
|
|
|
d1681e |
- */
|
|
|
d1681e |
- STACK_WIND_COOKIE (frame, dht_unlink_linkfile_cbk,
|
|
|
d1681e |
- hashed_subvol, hashed_subvol,
|
|
|
d1681e |
- hashed_subvol->fops->unlink, &local->loc,
|
|
|
d1681e |
- local->flags, xdata);
|
|
|
d1681e |
- return 0;
|
|
|
d1681e |
- }
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR) {
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setxattr, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, xdata);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ DHT_STACK_UNWIND (fsetxattr, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, xdata);
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
- dht_set_fixed_dir_stat (&local->preparent);
|
|
|
d1681e |
- dht_set_fixed_dir_stat (&local->postparent);
|
|
|
d1681e |
- DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
|
|
|
d1681e |
- &local->preparent, &local->postparent, xdata);
|
|
|
d1681e |
-
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
-dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
- int op_ret, int op_errno, dict_t *xdata)
|
|
|
d1681e |
+dht_xattrop_mds_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
|
|
|
d1681e |
{
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
- int this_call_cnt = 0;
|
|
|
d1681e |
- xlator_t *prev = NULL;
|
|
|
d1681e |
+ call_frame_t *prev = NULL;
|
|
|
d1681e |
|
|
|
d1681e |
local = frame->local;
|
|
|
d1681e |
prev = cookie;
|
|
|
d1681e |
|
|
|
d1681e |
- LOCK (&frame->lock);
|
|
|
d1681e |
- {
|
|
|
d1681e |
- if (op_ret == -1) {
|
|
|
d1681e |
- local->op_errno = op_errno;
|
|
|
d1681e |
- gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
- "subvolume %s returned -1",
|
|
|
d1681e |
- prev->name);
|
|
|
d1681e |
- goto unlock;
|
|
|
d1681e |
- }
|
|
|
d1681e |
-
|
|
|
d1681e |
- local->op_ret = 0;
|
|
|
d1681e |
+ if (op_ret == -1) {
|
|
|
d1681e |
+ local->op_errno = op_errno;
|
|
|
d1681e |
+ local->op_ret = op_ret;
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
+ "subvolume %s returned -1",
|
|
|
d1681e |
+ prev->this->name);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
}
|
|
|
d1681e |
-unlock:
|
|
|
d1681e |
- UNLOCK (&frame->lock);
|
|
|
d1681e |
|
|
|
d1681e |
- this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
- if (is_last_call (this_call_cnt)) {
|
|
|
d1681e |
- DHT_STACK_UNWIND (setxattr, frame, local->op_ret,
|
|
|
d1681e |
- local->op_errno, NULL);
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR) {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_setxattr_mds_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->setxattr,
|
|
|
d1681e |
+ &local->loc, local->xattr,
|
|
|
d1681e |
+ local->flags, local->xattr_req);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_setxattr_mds_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->fsetxattr,
|
|
|
d1681e |
+ local->fd, local->xattr,
|
|
|
d1681e |
+ local->flags, local->xattr_req);
|
|
|
d1681e |
}
|
|
|
d1681e |
-
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (local->fop == GF_FOP_SETXATTR)
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setxattr, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, xdata);
|
|
|
d1681e |
+ else
|
|
|
d1681e |
+ DHT_STACK_UNWIND (fsetxattr, frame, local->op_ret,
|
|
|
d1681e |
+ local->op_errno, xdata);
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
@@ -3371,6 +4241,41 @@ dht_linkinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_mds_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ VALIDATE_OR_GOTO (frame, out);
|
|
|
d1681e |
+ VALIDATE_OR_GOTO (frame->local, out);
|
|
|
d1681e |
+ VALIDATE_OR_GOTO (this->private, out);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!xattr || (op_ret == -1)) {
|
|
|
d1681e |
+ local->op_ret = op_ret;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (dict_get (xattr, conf->xattr_name)) {
|
|
|
d1681e |
+ dict_del (xattr, conf->xattr_name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ local->op_ret = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!local->xattr) {
|
|
|
d1681e |
+ local->xattr = dict_copy_with_ref (xattr, NULL);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno,
|
|
|
d1681e |
+ local->xattr, xdata);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
|
|
|
d1681e |
@@ -3600,6 +4505,7 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
|
|
|
d1681e |
xlator_t *subvol = NULL;
|
|
|
d1681e |
xlator_t *hashed_subvol = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
xlator_t *cached_subvol = NULL;
|
|
|
d1681e |
dht_conf_t *conf = NULL;
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
@@ -3642,6 +4548,12 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
if (key &&
|
|
|
d1681e |
+ (strncmp (key, conf->mds_xattr_key, strlen(key)) == 0)) {
|
|
|
d1681e |
+ op_errno = ENOTSUP;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (key &&
|
|
|
d1681e |
(strncmp (key, GF_XATTR_GET_REAL_FILENAME_KEY,
|
|
|
d1681e |
strlen (GF_XATTR_GET_REAL_FILENAME_KEY)) == 0)
|
|
|
d1681e |
&& DHT_IS_DIR(layout)) {
|
|
|
d1681e |
@@ -3771,26 +4683,53 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
- if (key && (!strcmp (QUOTA_LIMIT_KEY, key) ||
|
|
|
d1681e |
- !strcmp (QUOTA_LIMIT_OBJECTS_KEY, key))) {
|
|
|
d1681e |
- /* quota hardlimit and aggregated size of a directory is stored
|
|
|
d1681e |
- * in inode contexts of each brick. Hence its good enough that
|
|
|
d1681e |
- * we send getxattr for this key to any brick.
|
|
|
d1681e |
- */
|
|
|
d1681e |
- local->call_cnt = 1;
|
|
|
d1681e |
- subvol = dht_first_up_subvol (this);
|
|
|
d1681e |
- STACK_WIND (frame, dht_getxattr_cbk, subvol,
|
|
|
d1681e |
- subvol->fops->getxattr, loc, key, xdata);
|
|
|
d1681e |
- return 0;
|
|
|
d1681e |
- }
|
|
|
d1681e |
-
|
|
|
d1681e |
if (cluster_handle_marker_getxattr (frame, loc, key, conf->vol_uuid,
|
|
|
d1681e |
dht_getxattr_unwind,
|
|
|
d1681e |
dht_marker_populate_args) == 0)
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
|
|
|
d1681e |
if (DHT_IS_DIR(layout)) {
|
|
|
d1681e |
- cnt = local->call_cnt = layout->cnt;
|
|
|
d1681e |
+ local->call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+ cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_get (loc->inode, this, &mds_subvol);
|
|
|
d1681e |
+ if (!mds_subvol) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_INFO, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "Cannot determine MDS, fetching xattr %s randomly"
|
|
|
d1681e |
+ " from a subvol for path %s ", key, loc->path);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ /* TODO need to handle it, As of now we are
|
|
|
d1681e |
+ choosing availability instead of chossing
|
|
|
d1681e |
+ consistencty, in case of mds_subvol is
|
|
|
d1681e |
+ down winding a getxattr call on other subvol
|
|
|
d1681e |
+ and return xattr
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ local->mds_subvol = mds_subvol;
|
|
|
d1681e |
+ for (i = 0; i < cnt; i++) {
|
|
|
d1681e |
+ if (conf->subvolumes[i] == mds_subvol) {
|
|
|
d1681e |
+ if (!conf->subvolume_status[i]) {
|
|
|
d1681e |
+ gf_msg (this->name,
|
|
|
d1681e |
+ GF_LOG_INFO, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_DOWN,
|
|
|
d1681e |
+ "MDS %s is down for path"
|
|
|
d1681e |
+ " path %s so fetching xattr "
|
|
|
d1681e |
+ "%s randomly from a subvol ",
|
|
|
d1681e |
+ local->mds_subvol->name,
|
|
|
d1681e |
+ loc->path, key);
|
|
|
d1681e |
+ ret = 1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!ret && key && local->mds_subvol && dht_match_xattr (key)) {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_mds_getxattr_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->getxattr,
|
|
|
d1681e |
+ loc, key, xdata);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
} else {
|
|
|
d1681e |
cnt = local->call_cnt = 1;
|
|
|
d1681e |
}
|
|
|
d1681e |
@@ -3821,6 +4760,10 @@ dht_fgetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
int op_errno = -1;
|
|
|
d1681e |
int i = 0;
|
|
|
d1681e |
int cnt = 0;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+ char gfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
VALIDATE_OR_GOTO (frame, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (this, err);
|
|
|
d1681e |
@@ -3828,6 +4771,8 @@ dht_fgetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
VALIDATE_OR_GOTO (fd->inode, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (this->private, err);
|
|
|
d1681e |
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+
|
|
|
d1681e |
local = dht_local_init (frame, NULL, fd, GF_FOP_FGETXATTR);
|
|
|
d1681e |
if (!local) {
|
|
|
d1681e |
op_errno = ENOMEM;
|
|
|
d1681e |
@@ -3852,15 +4797,63 @@ dht_fgetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
}
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+ if (fd->inode)
|
|
|
d1681e |
+ gf_uuid_unparse(fd->inode->gfid, gfid);
|
|
|
d1681e |
+
|
|
|
d1681e |
if ((fd->inode->ia_type == IA_IFDIR)
|
|
|
d1681e |
&& key
|
|
|
d1681e |
&& (strncmp (key, GF_XATTR_LOCKINFO_KEY,
|
|
|
d1681e |
strlen (GF_XATTR_LOCKINFO_KEY)) != 0)) {
|
|
|
d1681e |
- cnt = local->call_cnt = layout->cnt;
|
|
|
d1681e |
+ local->call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+ cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_get (fd->inode, this, &mds_subvol);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!mds_subvol) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "cannot determine MDS, fetching xattr %s "
|
|
|
d1681e |
+ " randomly from a subvol for gfid %s ",
|
|
|
d1681e |
+ key, gfid);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ /* TODO need to handle it, As of now we are
|
|
|
d1681e |
+ choosing availability instead of chossing
|
|
|
d1681e |
+ consistencty, in case of hashed_subvol is
|
|
|
d1681e |
+ down winding a getxattr call on other subvol
|
|
|
d1681e |
+ and return xattr
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ local->mds_subvol = mds_subvol;
|
|
|
d1681e |
+ for (i = 0; i < cnt; i++) {
|
|
|
d1681e |
+ if (conf->subvolumes[i] == mds_subvol) {
|
|
|
d1681e |
+ if (!conf->subvolume_status[i]) {
|
|
|
d1681e |
+ gf_msg (this->name,
|
|
|
d1681e |
+ GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_DOWN,
|
|
|
d1681e |
+ "MDS subvolume %s is down"
|
|
|
d1681e |
+ " for gfid %s so fetching xattr "
|
|
|
d1681e |
+ " %s randomly from a subvol ",
|
|
|
d1681e |
+ local->mds_subvol->name,
|
|
|
d1681e |
+ gfid, key);
|
|
|
d1681e |
+ ret = 1;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!ret && key && local->mds_subvol &&
|
|
|
d1681e |
+ dht_match_xattr (key)) {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_mds_getxattr_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->fgetxattr,
|
|
|
d1681e |
+ fd, key, NULL);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
} else {
|
|
|
d1681e |
cnt = local->call_cnt = 1;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+
|
|
|
d1681e |
for (i = 0; i < cnt; i++) {
|
|
|
d1681e |
subvol = layout->list[i].xlator;
|
|
|
d1681e |
STACK_WIND (frame, dht_getxattr_cbk,
|
|
|
d1681e |
@@ -3956,6 +4949,169 @@ out:
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+/* Function is call by dict_foreach_fnmatch if key is match with
|
|
|
d1681e |
+ user.* and set boolean flag to true
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+static int
|
|
|
d1681e |
+dht_is_user_xattr (dict_t *this, char *key, data_t *value, void *data)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ gf_boolean_t *user_xattr_found = data;
|
|
|
d1681e |
+ *user_xattr_found = _gf_true;
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Common code to wind a (f)setxattr call to set xattr on directory
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_dir_common_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
d1681e |
+ fd_t *fd, dict_t *xattr, int flags, dict_t *xdata,
|
|
|
d1681e |
+ int *op_errno)
|
|
|
d1681e |
+
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dict_t *xattrop = NULL;
|
|
|
d1681e |
+ int32_t subone[1] = {-1};
|
|
|
d1681e |
+ gf_boolean_t uxattr_key_found = _gf_false;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ xlator_t *travvol = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ int i = 0;
|
|
|
d1681e |
+ int call_cnt = 0;
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+ local->flags = flags;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->gfid)
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Check if any user xattr present in xattr
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ dict_foreach_fnmatch (xattr, "user*", dht_is_user_xattr,
|
|
|
d1681e |
+ &uxattr_key_found);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Check if any custom key xattr present in dict xattr
|
|
|
d1681e |
+ and start index from 1 because user xattr already
|
|
|
d1681e |
+ checked in previous line
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ for (i = 1; xattrs_to_heal[i]; i++)
|
|
|
d1681e |
+ if (dict_get (xattr, xattrs_to_heal[i]))
|
|
|
d1681e |
+ uxattr_key_found = _gf_true;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* If there is no custom key xattr present or gfid is root
|
|
|
d1681e |
+ or call_cnt is 1 then wind a (f)setxattr call on all subvols
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (!uxattr_key_found || __is_root_gfid (local->gfid) || call_cnt == 1) {
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ travvol = conf->subvolumes[i];
|
|
|
d1681e |
+ if (fd) {
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, dht_err_cbk,
|
|
|
d1681e |
+ travvol, travvol,
|
|
|
d1681e |
+ travvol->fops->fsetxattr,
|
|
|
d1681e |
+ fd, xattr, flags, xdata);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, dht_err_cbk,
|
|
|
d1681e |
+ travvol, travvol,
|
|
|
d1681e |
+ travvol->fops->setxattr,
|
|
|
d1681e |
+ loc, xattr, flags, xdata);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* Calculate hash subvol based on inode and parent inode
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (fd) {
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_get (fd->inode, this, &mds_subvol);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_get (loc->inode, this, &mds_subvol);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (ret || !mds_subvol) {
|
|
|
d1681e |
+ if (fd) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "Failed to get mds subvol for fd %p"
|
|
|
d1681e |
+ "gfid is %s ", fd, gfid_local);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "Failed to get mds subvol for path %s"
|
|
|
d1681e |
+ "gfid is %s ", loc->path, gfid_local);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ (*op_errno) = ENOENT;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->mds_subvol = mds_subvol;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ if (conf->subvolumes[i] == mds_subvol) {
|
|
|
d1681e |
+ if (!conf->subvolume_status[i]) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING,
|
|
|
d1681e |
+ 0, DHT_MSG_HASHED_SUBVOL_DOWN,
|
|
|
d1681e |
+ "MDS subvol is down for path "
|
|
|
d1681e |
+ " %s gfid is %s Unable to set xattr " ,
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ (*op_errno) = ENOTCONN;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (uxattr_key_found) {
|
|
|
d1681e |
+ xattrop = dict_new ();
|
|
|
d1681e |
+ if (!xattrop) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY,
|
|
|
d1681e |
+ 0, "dictionary creation failed for path %s "
|
|
|
d1681e |
+ "for gfid is %s ", local->loc.path, gfid_local);
|
|
|
d1681e |
+ (*op_errno) = ENOMEM;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ local->xattr = dict_ref (xattr);
|
|
|
d1681e |
+ /* Subtract current MDS xattr value to -1 , value of MDS
|
|
|
d1681e |
+ xattr represents no. of times xattr modification failed
|
|
|
d1681e |
+ on non MDS subvols.
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ ret = dht_dict_set_array (xattrop, conf->mds_xattr_key, subone, 1);
|
|
|
d1681e |
+ if (ret != 0) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "dictionary set array failed for path %s "
|
|
|
d1681e |
+ "for gfid is %s ", local->loc.path, gfid_local);
|
|
|
d1681e |
+ if (xattrop)
|
|
|
d1681e |
+ dict_unref (xattrop);
|
|
|
d1681e |
+ (*op_errno) = ret;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* Wind a xattrop call to use ref counting approach
|
|
|
d1681e |
+ update mds xattr to -1 before update xattr on
|
|
|
d1681e |
+ hashed subvol and update mds xattr to +1 after update
|
|
|
d1681e |
+ xattr on all non hashed subvol
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (fd) {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_xattrop_mds_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->fxattrop,
|
|
|
d1681e |
+ fd, GF_XATTROP_ADD_ARRAY, xattrop, NULL);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ STACK_WIND (frame, dht_xattrop_mds_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->xattrop,
|
|
|
d1681e |
+ loc, GF_XATTROP_ADD_ARRAY,
|
|
|
d1681e |
+ xattrop, NULL);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (xattrop)
|
|
|
d1681e |
+ dict_unref (xattrop);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+err:
|
|
|
d1681e |
+ return -1;
|
|
|
d1681e |
+}
|
|
|
d1681e |
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
@@ -3969,7 +5125,6 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
dht_layout_t *layout = NULL;
|
|
|
d1681e |
int ret = -1;
|
|
|
d1681e |
int call_cnt = 0;
|
|
|
d1681e |
- int i = 0;
|
|
|
d1681e |
|
|
|
d1681e |
VALIDATE_OR_GOTO (frame, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (this, err);
|
|
|
d1681e |
@@ -4009,14 +5164,11 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
local->call_cnt = call_cnt = layout->cnt;
|
|
|
d1681e |
|
|
|
d1681e |
if (IA_ISDIR (fd->inode->ia_type)) {
|
|
|
d1681e |
- for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
- STACK_WIND_COOKIE (frame, dht_err_cbk,
|
|
|
d1681e |
- layout->list[i].xlator,
|
|
|
d1681e |
- layout->list[i].xlator,
|
|
|
d1681e |
- layout->list[i].xlator->fops->fsetxattr,
|
|
|
d1681e |
- fd, xattr, flags, xdata);
|
|
|
d1681e |
- }
|
|
|
d1681e |
-
|
|
|
d1681e |
+ local->hashed_subvol = NULL;
|
|
|
d1681e |
+ ret = dht_dir_common_setxattr (frame, this, NULL, fd,
|
|
|
d1681e |
+ xattr, flags, xdata, &op_errno);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
} else {
|
|
|
d1681e |
|
|
|
d1681e |
local->call_cnt = 1;
|
|
|
d1681e |
@@ -4043,16 +5195,6 @@ err:
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
-static int
|
|
|
d1681e |
-dht_common_setxattr_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
- xlator_t *this, int32_t op_ret, int32_t op_errno,
|
|
|
d1681e |
- dict_t *xdata)
|
|
|
d1681e |
-{
|
|
|
d1681e |
- DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
|
|
|
d1681e |
-
|
|
|
d1681e |
- return 0;
|
|
|
d1681e |
-}
|
|
|
d1681e |
-
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_checking_pathinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
@@ -4190,6 +5332,7 @@ dht_nuke_dir (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *tmp)
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_setxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
loc_t *loc, dict_t *xattr, int flags, dict_t *xdata)
|
|
|
d1681e |
@@ -4209,6 +5352,7 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
int call_cnt = 0;
|
|
|
d1681e |
uint32_t new_hash = 0;
|
|
|
d1681e |
|
|
|
d1681e |
+
|
|
|
d1681e |
VALIDATE_OR_GOTO (frame, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (this, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (loc, err);
|
|
|
d1681e |
@@ -4248,6 +5392,11 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
local->call_cnt = call_cnt = layout->cnt;
|
|
|
d1681e |
+ tmp = dict_get (xattr, conf->mds_xattr_key);
|
|
|
d1681e |
+ if (tmp) {
|
|
|
d1681e |
+ op_errno = ENOTSUP;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
|
|
|
d1681e |
tmp = dict_get (xattr, GF_XATTR_FILE_MIGRATE_KEY);
|
|
|
d1681e |
if (tmp) {
|
|
|
d1681e |
@@ -4423,15 +5572,11 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
local->xattr_req = xdata ? dict_ref (xdata) : dict_new ();
|
|
|
d1681e |
|
|
|
d1681e |
if (IA_ISDIR (loc->inode->ia_type)) {
|
|
|
d1681e |
-
|
|
|
d1681e |
- for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
- STACK_WIND_COOKIE (frame, dht_err_cbk,
|
|
|
d1681e |
- layout->list[i].xlator,
|
|
|
d1681e |
- layout->list[i].xlator,
|
|
|
d1681e |
- layout->list[i].xlator->fops->setxattr,
|
|
|
d1681e |
- loc, xattr, flags, xdata);
|
|
|
d1681e |
- }
|
|
|
d1681e |
-
|
|
|
d1681e |
+ local->hashed_subvol = NULL;
|
|
|
d1681e |
+ ret = dht_dir_common_setxattr (frame, this, loc, NULL,
|
|
|
d1681e |
+ xattr, flags, xdata, &op_errno);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
} else {
|
|
|
d1681e |
|
|
|
d1681e |
local->rebalance.xattr = dict_ref (xattr);
|
|
|
d1681e |
@@ -4670,6 +5815,12 @@ dht_removexattr (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
local->call_cnt = call_cnt = layout->cnt;
|
|
|
d1681e |
local->key = gf_strdup (key);
|
|
|
d1681e |
|
|
|
d1681e |
+ if (key &&
|
|
|
d1681e |
+ (strncmp (key, conf->mds_xattr_key, strlen(key)) == 0)) {
|
|
|
d1681e |
+ op_errno = ENOTSUP;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
if (IA_ISDIR (loc->inode->ia_type)) {
|
|
|
d1681e |
for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
STACK_WIND_COOKIE (frame, dht_removexattr_cbk,
|
|
|
d1681e |
@@ -7641,6 +8792,10 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
dht_iatt_merge (this, &local->postparent, postparent, prev);
|
|
|
d1681e |
|
|
|
d1681e |
local->call_cnt = conf->subvolume_cnt - 1;
|
|
|
d1681e |
+ /* Delete internal mds xattr from params dict to avoid store
|
|
|
d1681e |
+ internal mds xattr on other subvols
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ dict_del (local->params, conf->mds_xattr_key);
|
|
|
d1681e |
|
|
|
d1681e |
if (gf_uuid_is_null (local->loc.gfid))
|
|
|
d1681e |
gf_uuid_copy (local->loc.gfid, stbuf->ia_gfid);
|
|
|
d1681e |
@@ -7652,6 +8807,14 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
&local->loc, layout);
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+ /* Set hashed subvol as a mds subvol on inode ctx */
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_set (local->inode, this, hashed_subvol);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED,
|
|
|
d1681e |
+ "Failed to set hashed subvol for %s on inode vol is %s",
|
|
|
d1681e |
+ local->loc.path, hashed_subvol->name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
if (conf->subvolumes[i] == hashed_subvol)
|
|
|
d1681e |
continue;
|
|
|
d1681e |
@@ -7661,6 +8824,7 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
&local->loc, local->mode, local->umask,
|
|
|
d1681e |
local->params);
|
|
|
d1681e |
}
|
|
|
d1681e |
+
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
err:
|
|
|
d1681e |
if (local->op_ret != 0) {
|
|
|
d1681e |
@@ -7682,9 +8846,13 @@ dht_mkdir_guard_parent_layout_cbk (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
dict_t *params)
|
|
|
d1681e |
{
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = 0;
|
|
|
d1681e |
char pgfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ int32_t zero[1] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
local = frame->local;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
|
|
|
d1681e |
gf_uuid_unparse (loc->parent->gfid, pgfid);
|
|
|
d1681e |
|
|
|
d1681e |
@@ -7698,6 +8866,15 @@ dht_mkdir_guard_parent_layout_cbk (call_frame_t *frame, xlator_t *this,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
local->op_ret = -1;
|
|
|
d1681e |
+ /* Add internal MDS xattr on disk for hashed subvol
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ ret = dht_dict_set_array (params, conf->mds_xattr_key, zero, 1);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value:key = %s for "
|
|
|
d1681e |
+ "path %s", conf->mds_xattr_key, loc->path);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
|
|
|
d1681e |
STACK_WIND_COOKIE (frame, dht_mkdir_hashed_cbk, local->hashed_subvol,
|
|
|
d1681e |
local->hashed_subvol,
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
|
|
|
d1681e |
index 47a2e23..2aa7251 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-common.h
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-common.h
|
|
|
d1681e |
@@ -28,6 +28,7 @@
|
|
|
d1681e |
#define GF_XATTR_FIX_LAYOUT_KEY "distribute.fix.layout"
|
|
|
d1681e |
#define GF_XATTR_TIER_LAYOUT_FIXED_KEY "trusted.tier.fix.layout.complete"
|
|
|
d1681e |
#define GF_XATTR_FILE_MIGRATE_KEY "trusted.distribute.migrate-data"
|
|
|
d1681e |
+#define DHT_MDS_STR "mds"
|
|
|
d1681e |
#define GF_DHT_LOOKUP_UNHASHED_ON 1
|
|
|
d1681e |
#define GF_DHT_LOOKUP_UNHASHED_AUTO 2
|
|
|
d1681e |
#define DHT_PATHINFO_HEADER "DISTRIBUTE:"
|
|
|
d1681e |
@@ -43,6 +44,12 @@
|
|
|
d1681e |
#define DHT_DIR_STAT_BLOCKS 8
|
|
|
d1681e |
#define DHT_DIR_STAT_SIZE 4096
|
|
|
d1681e |
|
|
|
d1681e |
+/* Array to hold custom xattr keys
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+extern char *xattrs_to_heal[];
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
#include <fnmatch.h>
|
|
|
d1681e |
|
|
|
d1681e |
/* Array to hold custom xattr keys
|
|
|
d1681e |
@@ -116,6 +123,7 @@ struct dht_inode_ctx {
|
|
|
d1681e |
dht_layout_t *layout;
|
|
|
d1681e |
dht_stat_time_t time;
|
|
|
d1681e |
xlator_t *lock_subvol;
|
|
|
d1681e |
+ xlator_t *mds_subvol; /* This is only used for directories */
|
|
|
d1681e |
};
|
|
|
d1681e |
|
|
|
d1681e |
typedef struct dht_inode_ctx dht_inode_ctx_t;
|
|
|
d1681e |
@@ -262,6 +270,7 @@ struct dht_local {
|
|
|
d1681e |
/* Use stbuf as the postbuf, when we require both
|
|
|
d1681e |
* pre and post attrs */
|
|
|
d1681e |
struct iatt stbuf;
|
|
|
d1681e |
+ struct iatt mds_stbuf;
|
|
|
d1681e |
struct iatt prebuf;
|
|
|
d1681e |
struct iatt preoldparent;
|
|
|
d1681e |
struct iatt postoldparent;
|
|
|
d1681e |
@@ -273,6 +282,8 @@ struct dht_local {
|
|
|
d1681e |
inode_t *inode;
|
|
|
d1681e |
dict_t *params;
|
|
|
d1681e |
dict_t *xattr;
|
|
|
d1681e |
+ dict_t *mds_xattr;
|
|
|
d1681e |
+ dict_t *xdata; /* dict used to save xdata response by xattr fop */
|
|
|
d1681e |
dict_t *xattr_req;
|
|
|
d1681e |
dht_layout_t *layout;
|
|
|
d1681e |
size_t size;
|
|
|
d1681e |
@@ -281,7 +292,9 @@ struct dht_local {
|
|
|
d1681e |
xlator_t *dst_hashed, *dst_cached;
|
|
|
d1681e |
xlator_t *cached_subvol;
|
|
|
d1681e |
xlator_t *hashed_subvol;
|
|
|
d1681e |
+ xlator_t *mds_subvol; /* This is use for dir only */
|
|
|
d1681e |
char need_selfheal;
|
|
|
d1681e |
+ char need_xattr_heal;
|
|
|
d1681e |
int file_count;
|
|
|
d1681e |
int dir_count;
|
|
|
d1681e |
call_frame_t *main_frame;
|
|
|
d1681e |
@@ -365,6 +378,9 @@ struct dht_local {
|
|
|
d1681e |
|
|
|
d1681e |
/* fd open check */
|
|
|
d1681e |
gf_boolean_t fd_checked;
|
|
|
d1681e |
+ /* This is use only for directory operation */
|
|
|
d1681e |
+ int32_t valid;
|
|
|
d1681e |
+ gf_boolean_t heal_layout;
|
|
|
d1681e |
};
|
|
|
d1681e |
typedef struct dht_local dht_local_t;
|
|
|
d1681e |
|
|
|
d1681e |
@@ -651,6 +667,7 @@ struct dht_conf {
|
|
|
d1681e |
|
|
|
d1681e |
/* Support variable xattr names. */
|
|
|
d1681e |
char *xattr_name;
|
|
|
d1681e |
+ char *mds_xattr_key;
|
|
|
d1681e |
char *link_xattr_name;
|
|
|
d1681e |
char *commithash_xattr_name;
|
|
|
d1681e |
char *wild_xattr_name;
|
|
|
d1681e |
@@ -1333,9 +1350,6 @@ dht_normalize_stats (struct statvfs *buf, unsigned long bsize,
|
|
|
d1681e |
int
|
|
|
d1681e |
add_opt(char **optsp, const char *opt);
|
|
|
d1681e |
|
|
|
d1681e |
-char *
|
|
|
d1681e |
-getChoices (const char *value);
|
|
|
d1681e |
-
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_aggregate_split_brain_xattr (dict_t *dst, char *key, data_t *value);
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1345,18 +1359,12 @@ dht_remove_stale_linkto (void *data);
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_remove_stale_linkto_cbk (int ret, call_frame_t *sync_frame, void *data);
|
|
|
d1681e |
|
|
|
d1681e |
-
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_fd_ctx_set (xlator_t *this, fd_t *fd, xlator_t *subvol);
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_check_and_open_fd_on_subvol (xlator_t *this, call_frame_t *frame);
|
|
|
d1681e |
|
|
|
d1681e |
-
|
|
|
d1681e |
-
|
|
|
d1681e |
-
|
|
|
d1681e |
-
|
|
|
d1681e |
-
|
|
|
d1681e |
/* FD fop callbacks */
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
@@ -1409,12 +1417,10 @@ int
|
|
|
d1681e |
dht_file_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata);
|
|
|
d1681e |
|
|
|
d1681e |
-
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_file_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
int op_ret, int op_errno, dict_t *xdata);
|
|
|
d1681e |
|
|
|
d1681e |
-
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
int op_ret, int op_errno, dict_t *xdata);
|
|
|
d1681e |
@@ -1426,4 +1432,48 @@ int dht_request_iatt_in_xdata (xlator_t *this, dict_t *xattr_req);
|
|
|
d1681e |
|
|
|
d1681e |
int dht_read_iatt_from_xdata (xlator_t *this, dict_t *xdata,
|
|
|
d1681e |
struct iatt *stbuf);
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* All custom xattr heal functions */
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_dir_heal_xattrs (void *data);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_dir_heal_xattrs_done (int ret, call_frame_t *sync_frame, void *data);
|
|
|
d1681e |
+
|
|
|
d1681e |
+void
|
|
|
d1681e |
+dht_aggregate_xattr (dict_t *dst, dict_t *src);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int32_t
|
|
|
d1681e |
+dht_dict_set_array(dict_t *dict, char *key, int32_t value[], int32_t size);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_set_user_xattr (dict_t *dict, char *k, data_t *v, void *data);
|
|
|
d1681e |
+
|
|
|
d1681e |
+void
|
|
|
d1681e |
+dht_dir_set_heal_xattr (xlator_t *this, dht_local_t *local, dict_t *dst,
|
|
|
d1681e |
+ dict_t *src, int *uret, int *uflag);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_dir_xattr_heal (xlator_t *this, dht_local_t *local);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int32_t
|
|
|
d1681e |
+dht_dict_get_array (dict_t *dict, char *key, int32_t value[], int32_t size, int *errst);
|
|
|
d1681e |
+
|
|
|
d1681e |
+xlator_t *
|
|
|
d1681e |
+dht_inode_get_hashed_subvol (inode_t *inode, xlator_t *this, loc_t *loc);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_mark_mds_subvolume (call_frame_t *frame, xlator_t *this);
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_mds_internal_setxattr_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
+ xlator_t *this, int op_ret, int op_errno,
|
|
|
d1681e |
+ dict_t *xdata);
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_inode_ctx_mdsvol_set (inode_t *inode, xlator_t *this,
|
|
|
d1681e |
+ xlator_t *mds_subvol);
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_inode_ctx_mdsvol_get (inode_t *inode, xlator_t *this,
|
|
|
d1681e |
+ xlator_t **mdsvol);
|
|
|
d1681e |
+
|
|
|
d1681e |
#endif/* _DHT_H */
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
|
|
|
d1681e |
index e56a085..6e20aea 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-helper.c
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-helper.c
|
|
|
d1681e |
@@ -767,6 +767,10 @@ dht_local_wipe (xlator_t *this, dht_local_t *local)
|
|
|
d1681e |
|
|
|
d1681e |
if (local->xattr_req)
|
|
|
d1681e |
dict_unref (local->xattr_req);
|
|
|
d1681e |
+ if (local->mds_xattr)
|
|
|
d1681e |
+ dict_unref (local->mds_xattr);
|
|
|
d1681e |
+ if (local->xdata)
|
|
|
d1681e |
+ dict_unref (local->xdata);
|
|
|
d1681e |
|
|
|
d1681e |
if (local->selfheal.layout) {
|
|
|
d1681e |
dht_layout_unref (this, local->selfheal.layout);
|
|
|
d1681e |
@@ -2085,12 +2089,24 @@ dht_heal_full_path_done (int op_ret, call_frame_t *heal_frame, void *data)
|
|
|
d1681e |
|
|
|
d1681e |
call_frame_t *main_frame = NULL;
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *this = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
|
|
|
d1681e |
local = heal_frame->local;
|
|
|
d1681e |
main_frame = local->main_frame;
|
|
|
d1681e |
local->main_frame = NULL;
|
|
|
d1681e |
+ this = heal_frame->this;
|
|
|
d1681e |
|
|
|
d1681e |
dht_set_fixed_dir_stat (&local->postparent);
|
|
|
d1681e |
+ if (local->need_xattr_heal) {
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+ ret = dht_dir_xattr_heal (this, local);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "xattr heal failed for directory %s ",
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
|
|
|
d1681e |
DHT_STACK_UNWIND (lookup, main_frame, 0, 0,
|
|
|
d1681e |
local->inode, &local->stbuf, local->xattr,
|
|
|
d1681e |
@@ -2254,3 +2270,52 @@ dht_lk_inode_unref (call_frame_t *frame, int32_t op_ret)
|
|
|
d1681e |
out:
|
|
|
d1681e |
return ret;
|
|
|
d1681e |
}
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Code to update custom extended attributes from src dict to dst dict
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+void
|
|
|
d1681e |
+dht_dir_set_heal_xattr (xlator_t *this, dht_local_t *local, dict_t *dst,
|
|
|
d1681e |
+ dict_t *src, int *uret, int *uflag)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ data_t *keyval = NULL;
|
|
|
d1681e |
+ int luret = -1;
|
|
|
d1681e |
+ int luflag = -1;
|
|
|
d1681e |
+ int i = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!src || !dst) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, EINVAL,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "src or dst is NULL. Failed to set "
|
|
|
d1681e |
+ " dictionary value for path %s",
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ return;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* Check if any user xattr present in src dict and set
|
|
|
d1681e |
+ it to dst dict
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ luret = dict_foreach_fnmatch (src, "user.*",
|
|
|
d1681e |
+ dht_set_user_xattr, dst);
|
|
|
d1681e |
+ /* Check if any other custom xattr present in src dict
|
|
|
d1681e |
+ and set it to dst dict, here index start from 1 because
|
|
|
d1681e |
+ user xattr already checked in previous statement
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ for (i = 1; xattrs_to_heal[i]; i++) {
|
|
|
d1681e |
+ keyval = dict_get (src, xattrs_to_heal[i]);
|
|
|
d1681e |
+ if (keyval) {
|
|
|
d1681e |
+ luflag = 1;
|
|
|
d1681e |
+ ret = dict_set (dst, xattrs_to_heal[i], keyval);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value:key = %s for "
|
|
|
d1681e |
+ "path %s", xattrs_to_heal[i],
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ keyval = NULL;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (uret)
|
|
|
d1681e |
+ (*uret) = luret;
|
|
|
d1681e |
+ if (uflag)
|
|
|
d1681e |
+ (*uflag) = luflag;
|
|
|
d1681e |
+}
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
|
|
|
d1681e |
index 9709acf..7c596b1 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-inode-write.c
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-inode-write.c
|
|
|
d1681e |
@@ -1161,6 +1161,7 @@ dht_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
dht_iatt_merge (this, &local->stbuf, statpost, prev);
|
|
|
d1681e |
|
|
|
d1681e |
local->op_ret = 0;
|
|
|
d1681e |
+ local->op_errno = 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
unlock:
|
|
|
d1681e |
UNLOCK (&frame->lock);
|
|
|
d1681e |
@@ -1178,16 +1179,117 @@ unlock:
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
|
|
|
d1681e |
+/* Keep the existing code same for all the cases other than regular file */
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_non_mds_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, struct iatt *statpre,
|
|
|
d1681e |
+ struct iatt *statpost, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ int this_call_cnt = 0;
|
|
|
d1681e |
+ xlator_t *prev = NULL;
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ prev = cookie;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ LOCK (&frame->lock);
|
|
|
d1681e |
+ {
|
|
|
d1681e |
+ if (op_ret == -1) {
|
|
|
d1681e |
+ gf_msg (this->name, op_errno, 0,
|
|
|
d1681e |
+ 0, "subvolume %s returned -1",
|
|
|
d1681e |
+ prev->name);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ goto unlock;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ dht_iatt_merge (this, &local->prebuf, statpre, prev);
|
|
|
d1681e |
+ dht_iatt_merge (this, &local->stbuf, statpost, prev);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->op_ret = 0;
|
|
|
d1681e |
+ local->op_errno = 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+unlock:
|
|
|
d1681e |
+ UNLOCK (&frame->lock);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
+ if (is_last_call (this_call_cnt)) {
|
|
|
d1681e |
+ dht_inode_ctx_time_set (local->loc.inode, this, &local->stbuf);
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setattr, frame, 0, 0,
|
|
|
d1681e |
+ &local->prebuf, &local->stbuf, xdata);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_mds_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, struct iatt *statpre,
|
|
|
d1681e |
+ struct iatt *statpost, dict_t *xdata)
|
|
|
d1681e |
+
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+ xlator_t *prev = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ struct iatt loc_stbuf = {0,};
|
|
|
d1681e |
+ int i = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ prev = cookie;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ mds_subvol = local->mds_subvol;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (op_ret == -1) {
|
|
|
d1681e |
+ local->op_ret = op_ret;
|
|
|
d1681e |
+ local->op_errno = op_errno;
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_errno,
|
|
|
d1681e |
+ "subvolume %s returned -1",
|
|
|
d1681e |
+ prev->name);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->op_ret = 0;
|
|
|
d1681e |
+ loc_stbuf = local->stbuf;
|
|
|
d1681e |
+ dht_iatt_merge (this, &local->prebuf, statpre, prev);
|
|
|
d1681e |
+ dht_iatt_merge (this, &local->stbuf, statpost, prev);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->call_cnt = conf->subvolume_cnt - 1;
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ if (mds_subvol == conf->subvolumes[i])
|
|
|
d1681e |
+ continue;
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, dht_non_mds_setattr_cbk,
|
|
|
d1681e |
+ conf->subvolumes[i], conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i]->fops->setattr,
|
|
|
d1681e |
+ &local->loc, &loc_stbuf,
|
|
|
d1681e |
+ local->valid, local->xattr_req);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ DHT_STACK_UNWIND (setattr, frame, local->op_ret, local->op_errno,
|
|
|
d1681e |
+ &local->prebuf, &local->stbuf, xdata);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
d1681e |
struct iatt *stbuf, int32_t valid, dict_t *xdata)
|
|
|
d1681e |
{
|
|
|
d1681e |
- xlator_t *subvol = NULL;
|
|
|
d1681e |
- dht_layout_t *layout = NULL;
|
|
|
d1681e |
- dht_local_t *local = NULL;
|
|
|
d1681e |
- int op_errno = -1;
|
|
|
d1681e |
- int i = -1;
|
|
|
d1681e |
- int call_cnt = 0;
|
|
|
d1681e |
+ xlator_t *subvol = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ dht_layout_t *layout = NULL;
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ int op_errno = -1;
|
|
|
d1681e |
+ int i = -1;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ int call_cnt = 0;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
|
|
|
d1681e |
VALIDATE_OR_GOTO (frame, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (this, err);
|
|
|
d1681e |
@@ -1195,6 +1297,7 @@ dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
d1681e |
VALIDATE_OR_GOTO (loc->inode, err);
|
|
|
d1681e |
VALIDATE_OR_GOTO (loc->path, err);
|
|
|
d1681e |
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
local = dht_local_init (frame, loc, NULL, GF_FOP_SETATTR);
|
|
|
d1681e |
if (!local) {
|
|
|
d1681e |
op_errno = ENOMEM;
|
|
|
d1681e |
@@ -1235,12 +1338,50 @@ dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
d1681e |
|
|
|
d1681e |
local->call_cnt = call_cnt = layout->cnt;
|
|
|
d1681e |
|
|
|
d1681e |
- for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
- STACK_WIND_COOKIE (frame, dht_setattr_cbk,
|
|
|
d1681e |
- layout->list[i].xlator,
|
|
|
d1681e |
- layout->list[i].xlator,
|
|
|
d1681e |
- layout->list[i].xlator->fops->setattr,
|
|
|
d1681e |
+ if (IA_ISDIR (loc->inode->ia_type) &&
|
|
|
d1681e |
+ !__is_root_gfid (loc->inode->gfid) && call_cnt != 1) {
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_get (loc->inode, this, &mds_subvol);
|
|
|
d1681e |
+ if (ret || !mds_subvol) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "Failed to get mds subvol for path %s",
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ op_errno = EINVAL;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local->mds_subvol = mds_subvol;
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ if (conf->subvolumes[i] == mds_subvol) {
|
|
|
d1681e |
+ if (!conf->subvolume_status[i]) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING,
|
|
|
d1681e |
+ layout->list[i].err,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_DOWN,
|
|
|
d1681e |
+ "MDS subvol is down for path "
|
|
|
d1681e |
+ " %s Unable to set attr " ,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ op_errno = ENOTCONN;
|
|
|
d1681e |
+ goto err;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ local->valid = valid;
|
|
|
d1681e |
+ local->stbuf = *stbuf;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, dht_mds_setattr_cbk,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol,
|
|
|
d1681e |
+ local->mds_subvol->fops->setattr,
|
|
|
d1681e |
loc, stbuf, valid, xdata);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame, dht_setattr_cbk,
|
|
|
d1681e |
+ layout->list[i].xlator,
|
|
|
d1681e |
+ layout->list[i].xlator,
|
|
|
d1681e |
+ layout->list[i].xlator->fops->setattr,
|
|
|
d1681e |
+ loc, stbuf, valid, xdata);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-messages.h b/xlators/cluster/dht/src/dht-messages.h
|
|
|
d1681e |
index dcfd747..ade32e4 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-messages.h
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-messages.h
|
|
|
d1681e |
@@ -40,7 +40,7 @@
|
|
|
d1681e |
*/
|
|
|
d1681e |
|
|
|
d1681e |
#define GLFS_DHT_BASE GLFS_MSGID_COMP_DHT
|
|
|
d1681e |
-#define GLFS_DHT_NUM_MESSAGES 126
|
|
|
d1681e |
+#define GLFS_DHT_NUM_MESSAGES 129
|
|
|
d1681e |
#define GLFS_MSGID_END (GLFS_DHT_BASE + GLFS_DHT_NUM_MESSAGES + 1)
|
|
|
d1681e |
|
|
|
d1681e |
/* Messages with message IDs */
|
|
|
d1681e |
@@ -1083,6 +1083,7 @@
|
|
|
d1681e |
* @diagnosis
|
|
|
d1681e |
* @recommendedaction None
|
|
|
d1681e |
*/
|
|
|
d1681e |
+
|
|
|
d1681e |
#define DHT_MSG_DIR_LOOKUP_FAILED (GLFS_DHT_BASE + 118)
|
|
|
d1681e |
|
|
|
d1681e |
/*
|
|
|
d1681e |
@@ -1111,6 +1112,7 @@
|
|
|
d1681e |
* @diagnosis
|
|
|
d1681e |
* @recommendedaction None
|
|
|
d1681e |
*/
|
|
|
d1681e |
+
|
|
|
d1681e |
#define DHT_MSG_ENTRYLK_ERROR (GLFS_DHT_BASE + 122)
|
|
|
d1681e |
|
|
|
d1681e |
/*
|
|
|
d1681e |
@@ -1132,7 +1134,7 @@
|
|
|
d1681e |
* @diagnosis
|
|
|
d1681e |
* @recommendedaction None
|
|
|
d1681e |
*/
|
|
|
d1681e |
-#define DHT_MSG_UNKNOWN_FOP (GLFS_DHT_BASE + 125)
|
|
|
d1681e |
+#define DHT_MSG_UNKNOWN_FOP (GLFS_DHT_BASE + 125)
|
|
|
d1681e |
|
|
|
d1681e |
/*
|
|
|
d1681e |
* @messageid 109126
|
|
|
d1681e |
@@ -1141,5 +1143,27 @@
|
|
|
d1681e |
*/
|
|
|
d1681e |
#define DHT_MSG_MIGRATE_FILE_SKIPPED (GLFS_DHT_BASE + 126)
|
|
|
d1681e |
|
|
|
d1681e |
+/*
|
|
|
d1681e |
+ * @messageid 109127
|
|
|
d1681e |
+ * @diagnosis
|
|
|
d1681e |
+ * @recommendedaction None
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+#define DHT_MSG_DIR_XATTR_HEAL_FAILED (GLFS_DHT_BASE + 127)
|
|
|
d1681e |
+
|
|
|
d1681e |
+/*
|
|
|
d1681e |
+ * @messageid 109128
|
|
|
d1681e |
+ * @diagnosis
|
|
|
d1681e |
+ * @recommendedaction None
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+#define DHT_MSG_HASHED_SUBVOL_DOWN (GLFS_DHT_BASE + 128)
|
|
|
d1681e |
+
|
|
|
d1681e |
+/*
|
|
|
d1681e |
+ * @messageid 109129
|
|
|
d1681e |
+ * @diagnosis
|
|
|
d1681e |
+ * @recommendedaction None
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+#define DHT_MSG_NON_HASHED_SUBVOL_DOWN (GLFS_DHT_BASE + 129)
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
|
|
|
d1681e |
#endif /* _DHT_MESSAGES_H_ */
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
|
|
|
d1681e |
index 3b9fcf1..328251d 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-selfheal.c
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-selfheal.c
|
|
|
d1681e |
@@ -703,6 +703,18 @@ dht_selfheal_dir_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+/* Code is required to set user xattr to local->xattr
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_set_user_xattr (dict_t *dict, char *k, data_t *v, void *data)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dict_t *set_xattr = data;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = dict_set (set_xattr, k, v);
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
|
|
|
d1681e |
@@ -830,7 +842,6 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
|
|
|
d1681e |
err:
|
|
|
d1681e |
if (xattr)
|
|
|
d1681e |
dict_unref (xattr);
|
|
|
d1681e |
-
|
|
|
d1681e |
if (xdata)
|
|
|
d1681e |
dict_unref (xdata);
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1128,6 +1139,14 @@ dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
|
|
|
d1681e |
if (is_last_call (this_call_cnt)) {
|
|
|
d1681e |
+ if (!local->heal_layout) {
|
|
|
d1681e |
+ gf_msg_trace (this->name, 0,
|
|
|
d1681e |
+ "Skip heal layout for %s gfid = %s ",
|
|
|
d1681e |
+ local->loc.path, uuid_utoa(local->gfid));
|
|
|
d1681e |
+
|
|
|
d1681e |
+ dht_selfheal_dir_finish (frame, this, 0, 1);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
ret = dht_selfheal_layout_lock (frame, layout, _gf_false,
|
|
|
d1681e |
dht_selfheal_dir_xattr,
|
|
|
d1681e |
dht_should_heal_layout);
|
|
|
d1681e |
@@ -1140,6 +1159,141 @@ dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_selfheal_dir_check_set_mdsxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
d1681e |
+ int op_ret, int op_errno, dict_t *xdata)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *prev = cookie;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ dht_conf_t *conf = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (op_ret) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, op_ret,
|
|
|
d1681e |
+ "internal mds setxattr %s is failed on mds subvol "
|
|
|
d1681e |
+ "at the time of heal on path %s " ,
|
|
|
d1681e |
+ conf->mds_xattr_key, local->loc.path);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ /* Save mds subvol on inode ctx */
|
|
|
d1681e |
+ ret = dht_inode_ctx_mdsvol_set (local->inode, this, prev);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_SET_INODE_CTX_FAILED,
|
|
|
d1681e |
+ "Failed to set hashed subvol "
|
|
|
d1681e |
+ " %s for %s ", prev->name,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ DHT_STACK_DESTROY (frame);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+/* Code to set internal mds xattr if it is not present
|
|
|
d1681e |
+*/
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_selfheal_dir_check_set_mdsxattr (call_frame_t *frame, loc_t *loc)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *this = NULL;
|
|
|
d1681e |
+ xlator_t *hashed_subvol = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ dict_t *xattrs = NULL;
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0,};
|
|
|
d1681e |
+ int32_t zero[1] = {0};
|
|
|
d1681e |
+ call_frame_t *xattr_frame = NULL;
|
|
|
d1681e |
+ dht_local_t *copy_local = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = 0;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ this = frame->this;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!dict_get (local->xattr, conf->mds_xattr_key)) {
|
|
|
d1681e |
+ /* It means no internal MDS xattr has been set yet
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ /* Calculate hashed subvol based on inode and
|
|
|
d1681e |
+ parent inode
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ hashed_subvol = dht_inode_get_hashed_subvol (local->inode, this,
|
|
|
d1681e |
+ loc);
|
|
|
d1681e |
+ if (!hashed_subvol) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_DEBUG, 0,
|
|
|
d1681e |
+ DHT_MSG_HASHED_SUBVOL_GET_FAILED,
|
|
|
d1681e |
+ "Failed to get hashed subvol for path %s"
|
|
|
d1681e |
+ "gfid is %s ",
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ /* Set internal mds xattr on disk */
|
|
|
d1681e |
+ xattrs = dict_new ();
|
|
|
d1681e |
+ if (!xattrs) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_NO_MEMORY, "dict_new failed");
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* Add internal MDS xattr on disk for hashed subvol
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ ret = dht_dict_set_array (xattrs, conf->mds_xattr_key, zero, 1);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary"
|
|
|
d1681e |
+ " value:key = %s for "
|
|
|
d1681e |
+ "path %s", conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ xattr_frame = create_frame (this, this->ctx->pool);
|
|
|
d1681e |
+ if (!xattr_frame) {
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ copy_local = dht_local_init (xattr_frame, &(local->loc),
|
|
|
d1681e |
+ NULL, 0);
|
|
|
d1681e |
+ if (!copy_local) {
|
|
|
d1681e |
+ ret = -1;
|
|
|
d1681e |
+ DHT_STACK_DESTROY (xattr_frame);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ copy_local->stbuf = local->stbuf;
|
|
|
d1681e |
+ copy_local->inode = inode_ref (local->inode);
|
|
|
d1681e |
+ gf_uuid_copy (copy_local->loc.gfid, local->gfid);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ STACK_WIND_COOKIE (xattr_frame,
|
|
|
d1681e |
+ dht_selfheal_dir_check_set_mdsxattr_cbk,
|
|
|
d1681e |
+ (void *)hashed_subvol, hashed_subvol,
|
|
|
d1681e |
+ hashed_subvol->fops->setxattr,
|
|
|
d1681e |
+ loc, xattrs, 0, NULL);
|
|
|
d1681e |
+ ret = 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ ret = 0;
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "internal xattr %s is present on subvol"
|
|
|
d1681e |
+ "on path %s gfid is %s " , conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path, gfid_local);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (xattrs)
|
|
|
d1681e |
+ dict_unref (xattrs);
|
|
|
d1681e |
+ return ret;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
|
|
|
d1681e |
@@ -1159,7 +1313,40 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
|
|
|
d1681e |
missing_attr++;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+ if (!__is_root_gfid (local->stbuf.ia_gfid)) {
|
|
|
d1681e |
+ if (local->need_xattr_heal) {
|
|
|
d1681e |
+ local->need_xattr_heal = 0;
|
|
|
d1681e |
+ ret = dht_dir_xattr_heal (this, local);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR,
|
|
|
d1681e |
+ ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "xattr heal failed for "
|
|
|
d1681e |
+ "directory %s gfid %s ",
|
|
|
d1681e |
+ local->loc.path,
|
|
|
d1681e |
+ local->gfid);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ ret = dht_selfheal_dir_check_set_mdsxattr (frame, loc);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_INFO, ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "set mds internal xattr failed for "
|
|
|
d1681e |
+ "directory %s gfid %s ", local->loc.path,
|
|
|
d1681e |
+ local->gfid);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!gf_uuid_is_null (local->gfid))
|
|
|
d1681e |
+ gf_uuid_copy (loc->gfid, local->gfid);
|
|
|
d1681e |
+
|
|
|
d1681e |
if (missing_attr == 0) {
|
|
|
d1681e |
+ if (!local->heal_layout) {
|
|
|
d1681e |
+ gf_msg_trace (this->name, 0,
|
|
|
d1681e |
+ "Skip heal layout for %s gfid = %s ",
|
|
|
d1681e |
+ loc->path, uuid_utoa(loc->gfid));
|
|
|
d1681e |
+ dht_selfheal_dir_finish (frame, this, 0, 1);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
ret = dht_selfheal_layout_lock (frame, layout, _gf_false,
|
|
|
d1681e |
dht_selfheal_dir_xattr,
|
|
|
d1681e |
dht_should_heal_layout);
|
|
|
d1681e |
@@ -1171,11 +1358,9 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
- if (!gf_uuid_is_null (local->gfid))
|
|
|
d1681e |
- gf_uuid_copy (loc->gfid, local->gfid);
|
|
|
d1681e |
-
|
|
|
d1681e |
local->call_cnt = missing_attr;
|
|
|
d1681e |
cnt = layout->cnt;
|
|
|
d1681e |
+
|
|
|
d1681e |
for (i = 0; i < cnt; i++) {
|
|
|
d1681e |
if (layout->list[i].err == -1) {
|
|
|
d1681e |
gf_msg_trace (this->name, 0,
|
|
|
d1681e |
@@ -1291,16 +1476,66 @@ out:
|
|
|
d1681e |
return;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
+
|
|
|
d1681e |
+void
|
|
|
d1681e |
+dht_selfheal_dir_mkdir_setquota (dict_t *src, dict_t *dst)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ data_t *quota_limit_key = NULL;
|
|
|
d1681e |
+ data_t *quota_limit_obj_key = NULL;
|
|
|
d1681e |
+ xlator_t *this = NULL;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ GF_ASSERT (src);
|
|
|
d1681e |
+ GF_ASSERT (dst);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ this = THIS;
|
|
|
d1681e |
+ GF_ASSERT (this);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ quota_limit_key = dict_get (src, QUOTA_LIMIT_KEY);
|
|
|
d1681e |
+ if (!quota_limit_key) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "QUOTA_LIMIT_KEY xattr not present");
|
|
|
d1681e |
+ goto cont;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ ret = dict_set(dst, QUOTA_LIMIT_KEY, quota_limit_key);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value.key = %s",
|
|
|
d1681e |
+ QUOTA_LIMIT_KEY);
|
|
|
d1681e |
+
|
|
|
d1681e |
+cont:
|
|
|
d1681e |
+ quota_limit_obj_key = dict_get (src, QUOTA_LIMIT_OBJECTS_KEY);
|
|
|
d1681e |
+ if (!quota_limit_obj_key) {
|
|
|
d1681e |
+ gf_msg_debug (this->name, 0,
|
|
|
d1681e |
+ "QUOTA_LIMIT_OBJECTS_KEY xattr not present");
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ ret = dict_set (dst, QUOTA_LIMIT_OBJECTS_KEY, quota_limit_obj_key);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value.key = %s",
|
|
|
d1681e |
+ QUOTA_LIMIT_OBJECTS_KEY);
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ return;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
int
|
|
|
d1681e |
dht_selfheal_dir_mkdir_lookup_done (call_frame_t *frame, xlator_t *this)
|
|
|
d1681e |
{
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
int i = 0;
|
|
|
d1681e |
- int ret = -1;
|
|
|
d1681e |
dict_t *dict = NULL;
|
|
|
d1681e |
dht_layout_t *layout = NULL;
|
|
|
d1681e |
loc_t *loc = NULL;
|
|
|
d1681e |
int cnt = 0;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
|
|
|
d1681e |
VALIDATE_OR_GOTO (this->private, err);
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1324,9 +1559,11 @@ dht_selfheal_dir_mkdir_lookup_done (call_frame_t *frame, xlator_t *this)
|
|
|
d1681e |
|
|
|
d1681e |
dict = dict_ref (local->params);
|
|
|
d1681e |
}
|
|
|
d1681e |
- /* Set acls */
|
|
|
d1681e |
- if (local->xattr && dict)
|
|
|
d1681e |
- dht_selfheal_dir_mkdir_setacl (local->xattr, dict);
|
|
|
d1681e |
+ /* Code to update all extended attributed from local->xattr
|
|
|
d1681e |
+ to dict
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ dht_dir_set_heal_xattr (this, local, dict, local->xattr, NULL,
|
|
|
d1681e |
+ NULL);
|
|
|
d1681e |
|
|
|
d1681e |
if (!dict)
|
|
|
d1681e |
gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
@@ -1374,8 +1611,13 @@ dht_selfheal_dir_mkdir_lookup_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
int this_call_cnt = 0;
|
|
|
d1681e |
int missing_dirs = 0;
|
|
|
d1681e |
dht_layout_t *layout = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = 0;
|
|
|
d1681e |
loc_t *loc = NULL;
|
|
|
d1681e |
xlator_t *prev = NULL;
|
|
|
d1681e |
+ int check_mds = 0;
|
|
|
d1681e |
+ int errst = 0;
|
|
|
d1681e |
+ int32_t mds_xattr_val[1] = {0};
|
|
|
d1681e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
VALIDATE_OR_GOTO (this->private, err);
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1383,6 +1625,10 @@ dht_selfheal_dir_mkdir_lookup_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
layout = local->layout;
|
|
|
d1681e |
loc = &local->loc;
|
|
|
d1681e |
prev = cookie;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (local->gfid)
|
|
|
d1681e |
+ gf_uuid_unparse(local->gfid, gfid_local);
|
|
|
d1681e |
|
|
|
d1681e |
this_call_cnt = dht_frame_return (frame);
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1397,6 +1643,12 @@ dht_selfheal_dir_mkdir_lookup_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
if (!op_ret) {
|
|
|
d1681e |
dht_iatt_merge (this, &local->stbuf, stbuf, prev);
|
|
|
d1681e |
}
|
|
|
d1681e |
+ check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key,
|
|
|
d1681e |
+ mds_xattr_val, 1, &errst);
|
|
|
d1681e |
+ if (dict_get (xattr, conf->mds_xattr_key) && check_mds && !errst) {
|
|
|
d1681e |
+ dict_unref (local->xattr);
|
|
|
d1681e |
+ local->xattr = dict_ref (xattr);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
|
|
|
d1681e |
}
|
|
|
d1681e |
UNLOCK (&frame->lock);
|
|
|
d1681e |
@@ -1445,13 +1697,16 @@ dht_selfheal_dir_mkdir_lock_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
dht_local_t *local = NULL;
|
|
|
d1681e |
dht_conf_t *conf = NULL;
|
|
|
d1681e |
int i = 0;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
|
|
|
d1681e |
VALIDATE_OR_GOTO (this->private, err);
|
|
|
d1681e |
|
|
|
d1681e |
conf = this->private;
|
|
|
d1681e |
local = frame->local;
|
|
|
d1681e |
+ mds_subvol = local->mds_subvol;
|
|
|
d1681e |
|
|
|
d1681e |
- local->call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+ local->call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
|
|
|
d1681e |
if (op_ret < 0) {
|
|
|
d1681e |
|
|
|
d1681e |
@@ -1477,12 +1732,32 @@ dht_selfheal_dir_mkdir_lock_cbk (call_frame_t *frame, void *cookie,
|
|
|
d1681e |
/* After getting locks, perform lookup again to ensure that the
|
|
|
d1681e |
directory was not deleted by a racing rmdir
|
|
|
d1681e |
*/
|
|
|
d1681e |
+ if (!local->xattr_req)
|
|
|
d1681e |
+ local->xattr_req = dict_new ();
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = dict_set_int32 (local->xattr_req, "list-xattr", 1);
|
|
|
d1681e |
+ if (ret)
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary key list-xattr value "
|
|
|
d1681e |
+ " for path %s ", local->loc.path);
|
|
|
d1681e |
|
|
|
d1681e |
for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
- STACK_WIND_COOKIE (frame, dht_selfheal_dir_mkdir_lookup_cbk,
|
|
|
d1681e |
- conf->subvolumes[i], conf->subvolumes[i],
|
|
|
d1681e |
- conf->subvolumes[i]->fops->lookup,
|
|
|
d1681e |
- &local->loc, NULL);
|
|
|
d1681e |
+ if (mds_subvol && conf->subvolumes[i] == mds_subvol) {
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame,
|
|
|
d1681e |
+ dht_selfheal_dir_mkdir_lookup_cbk,
|
|
|
d1681e |
+ conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i]->fops->lookup,
|
|
|
d1681e |
+ &local->loc, local->xattr_req);
|
|
|
d1681e |
+ } else {
|
|
|
d1681e |
+ STACK_WIND_COOKIE (frame,
|
|
|
d1681e |
+ dht_selfheal_dir_mkdir_lookup_cbk,
|
|
|
d1681e |
+ conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i],
|
|
|
d1681e |
+ conf->subvolumes[i]->fops->lookup,
|
|
|
d1681e |
+ &local->loc, NULL);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
return 0;
|
|
|
d1681e |
@@ -2171,15 +2446,16 @@ dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
dht_layout_sort_volname (layout);
|
|
|
d1681e |
+ local->heal_layout = _gf_true;
|
|
|
d1681e |
ret = dht_selfheal_dir_getafix (frame, loc, layout);
|
|
|
d1681e |
|
|
|
d1681e |
if (ret == -1) {
|
|
|
d1681e |
- gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_INFO, 0,
|
|
|
d1681e |
DHT_MSG_DIR_SELFHEAL_FAILED,
|
|
|
d1681e |
"Directory selfheal failed: "
|
|
|
d1681e |
"Unable to form layout for directory %s",
|
|
|
d1681e |
loc->path);
|
|
|
d1681e |
- goto sorry_no_fix;
|
|
|
d1681e |
+ local->heal_layout = _gf_false;
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
dht_selfheal_dir_mkdir (frame, loc, layout, 0);
|
|
|
d1681e |
@@ -2281,23 +2557,196 @@ dht_selfheal_restore (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
int
|
|
|
d1681e |
+dht_dir_heal_xattrs (void *data)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ call_frame_t *frame = NULL;
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *subvol = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ xlator_t *this = NULL;
|
|
|
d1681e |
+ dht_conf_t *conf = NULL;
|
|
|
d1681e |
+ dict_t *user_xattr = NULL;
|
|
|
d1681e |
+ dict_t *internal_xattr = NULL;
|
|
|
d1681e |
+ dict_t *mds_xattr = NULL;
|
|
|
d1681e |
+ dict_t *xdata = NULL;
|
|
|
d1681e |
+ int call_cnt = 0;
|
|
|
d1681e |
+ int ret = -1;
|
|
|
d1681e |
+ int uret = 0;
|
|
|
d1681e |
+ int uflag = 0;
|
|
|
d1681e |
+ int i = 0;
|
|
|
d1681e |
+ int xattr_hashed = 0;
|
|
|
d1681e |
+ char gfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ int32_t allzero[1] = {0};
|
|
|
d1681e |
+
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO ("dht", data, out);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ frame = data;
|
|
|
d1681e |
+ local = frame->local;
|
|
|
d1681e |
+ this = frame->this;
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO ("dht", this, out);
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, local, out);
|
|
|
d1681e |
+ mds_subvol = local->mds_subvol;
|
|
|
d1681e |
+ conf = this->private;
|
|
|
d1681e |
+ GF_VALIDATE_OR_GOTO (this->name, conf, out);
|
|
|
d1681e |
+ gf_uuid_unparse(local->loc.gfid, gfid);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!mds_subvol) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "No mds subvol for %s gfid = %s",
|
|
|
d1681e |
+ local->loc.path, gfid);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if ((local->loc.inode && gf_uuid_is_null (local->loc.inode->gfid)) ||
|
|
|
d1681e |
+ gf_uuid_is_null (local->loc.gfid)) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "No gfid present so skip heal for path %s gfid = %s",
|
|
|
d1681e |
+ local->loc.path, gfid);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ internal_xattr = dict_new ();
|
|
|
d1681e |
+ if (!internal_xattr) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0,
|
|
|
d1681e |
+ "dictionary creation failed");
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ xdata = dict_new ();
|
|
|
d1681e |
+ if (!xdata) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0,
|
|
|
d1681e |
+ "dictionary creation failed");
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ user_xattr = dict_new ();
|
|
|
d1681e |
+ if (!user_xattr) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0,
|
|
|
d1681e |
+ "dictionary creation failed");
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ ret = syncop_listxattr (local->mds_subvol, &local->loc,
|
|
|
d1681e |
+ &mds_xattr, NULL, NULL);
|
|
|
d1681e |
+ if (ret < 0) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, -ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "failed to list xattrs for "
|
|
|
d1681e |
+ "%s: on %s ",
|
|
|
d1681e |
+ local->loc.path, local->mds_subvol->name);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!mds_xattr)
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ dht_dir_set_heal_xattr (this, local, user_xattr, mds_xattr,
|
|
|
d1681e |
+ &uret, &uflag);
|
|
|
d1681e |
+
|
|
|
d1681e |
+ /* To set quota related xattr need to set GLUSTERFS_INTERNAL_FOP_KEY
|
|
|
d1681e |
+ * key value to 1
|
|
|
d1681e |
+ */
|
|
|
d1681e |
+ if (dict_get (user_xattr, QUOTA_LIMIT_KEY) ||
|
|
|
d1681e |
+ dict_get (user_xattr, QUOTA_LIMIT_OBJECTS_KEY)) {
|
|
|
d1681e |
+ ret = dict_set_int32 (xdata, GLUSTERFS_INTERNAL_FOP_KEY, 1);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value: key = %s,"
|
|
|
d1681e |
+ " path = %s", GLUSTERFS_INTERNAL_FOP_KEY,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ if (uret <= 0 && !uflag)
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+
|
|
|
d1681e |
+ for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
+ subvol = conf->subvolumes[i];
|
|
|
d1681e |
+ if (subvol == mds_subvol)
|
|
|
d1681e |
+ continue;
|
|
|
d1681e |
+ if (uret || uflag) {
|
|
|
d1681e |
+ ret = syncop_setxattr (subvol, &local->loc, user_xattr,
|
|
|
d1681e |
+ 0, xdata, NULL);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ xattr_hashed = 1;
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, -ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "Directory xattr heal failed. Failed to set"
|
|
|
d1681e |
+ "user xattr on path %s on "
|
|
|
d1681e |
+ "subvol %s, gfid = %s ",
|
|
|
d1681e |
+ local->loc.path, subvol->name, gfid);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ /* After heal all custom xattr reset internal MDS xattr to 0 */
|
|
|
d1681e |
+ if (!xattr_hashed) {
|
|
|
d1681e |
+ ret = dht_dict_set_array (internal_xattr,
|
|
|
d1681e |
+ conf->mds_xattr_key,
|
|
|
d1681e |
+ allzero, 1);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, ENOMEM,
|
|
|
d1681e |
+ DHT_MSG_DICT_SET_FAILED,
|
|
|
d1681e |
+ "Failed to set dictionary value:key = %s for "
|
|
|
d1681e |
+ "path %s", conf->mds_xattr_key,
|
|
|
d1681e |
+ local->loc.path);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ ret = syncop_setxattr (mds_subvol, &local->loc, internal_xattr,
|
|
|
d1681e |
+ 0, NULL, NULL);
|
|
|
d1681e |
+ if (ret) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, -ret,
|
|
|
d1681e |
+ DHT_MSG_DIR_XATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "Failed to reset internal xattr "
|
|
|
d1681e |
+ "on path %s on subvol %s"
|
|
|
d1681e |
+ "gfid = %s ", local->loc.path,
|
|
|
d1681e |
+ mds_subvol->name, gfid);
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+out:
|
|
|
d1681e |
+ if (user_xattr)
|
|
|
d1681e |
+ dict_unref (user_xattr);
|
|
|
d1681e |
+ if (mds_xattr)
|
|
|
d1681e |
+ dict_unref (mds_xattr);
|
|
|
d1681e |
+ if (internal_xattr)
|
|
|
d1681e |
+ dict_unref (internal_xattr);
|
|
|
d1681e |
+ if (xdata)
|
|
|
d1681e |
+ dict_unref (xdata);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
+dht_dir_heal_xattrs_done (int ret, call_frame_t *sync_frame, void *data)
|
|
|
d1681e |
+{
|
|
|
d1681e |
+ DHT_STACK_DESTROY (sync_frame);
|
|
|
d1681e |
+ return 0;
|
|
|
d1681e |
+}
|
|
|
d1681e |
+
|
|
|
d1681e |
+
|
|
|
d1681e |
+int
|
|
|
d1681e |
dht_dir_attr_heal (void *data)
|
|
|
d1681e |
{
|
|
|
d1681e |
- call_frame_t *frame = NULL;
|
|
|
d1681e |
- dht_local_t *local = NULL;
|
|
|
d1681e |
- xlator_t *subvol = NULL;
|
|
|
d1681e |
- xlator_t *this = NULL;
|
|
|
d1681e |
+ call_frame_t *frame = NULL;
|
|
|
d1681e |
+ dht_local_t *local = NULL;
|
|
|
d1681e |
+ xlator_t *subvol = NULL;
|
|
|
d1681e |
+ xlator_t *mds_subvol = NULL;
|
|
|
d1681e |
+ xlator_t *this = NULL;
|
|
|
d1681e |
dht_conf_t *conf = NULL;
|
|
|
d1681e |
int call_cnt = 0;
|
|
|
d1681e |
int ret = -1;
|
|
|
d1681e |
int i = 0;
|
|
|
d1681e |
- char gfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
+ char gfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
d1681e |
|
|
|
d1681e |
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", data, out);
|
|
|
d1681e |
|
|
|
d1681e |
frame = data;
|
|
|
d1681e |
local = frame->local;
|
|
|
d1681e |
+ mds_subvol = local->mds_subvol;
|
|
|
d1681e |
this = frame->this;
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", this, out);
|
|
|
d1681e |
GF_VALIDATE_OR_GOTO ("dht", local, out);
|
|
|
d1681e |
@@ -2306,17 +2755,39 @@ dht_dir_attr_heal (void *data)
|
|
|
d1681e |
|
|
|
d1681e |
call_cnt = conf->subvolume_cnt;
|
|
|
d1681e |
|
|
|
d1681e |
+ if (!__is_root_gfid (local->stbuf.ia_gfid) && (!mds_subvol)) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
d1681e |
+ DHT_MSG_DIR_ATTR_HEAL_FAILED,
|
|
|
d1681e |
+ "No mds subvol for %s gfid = %s",
|
|
|
d1681e |
+ local->loc.path, gfid);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
+ if (!__is_root_gfid (local->stbuf.ia_gfid)) {
|
|
|
d1681e |
+ for (i = 0; i < conf->subvolume_cnt; i++) {
|
|
|
d1681e |
+ if (conf->subvolumes[i] == mds_subvol) {
|
|
|
d1681e |
+ if (!conf->subvolume_status[i]) {
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR,
|
|
|
d1681e |
+ 0, DHT_MSG_HASHED_SUBVOL_DOWN,
|
|
|
d1681e |
+ "mds subvol is down for path "
|
|
|
d1681e |
+ " %s gfid is %s Unable to set xattr " ,
|
|
|
d1681e |
+ local->loc.path, gfid);
|
|
|
d1681e |
+ goto out;
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+ }
|
|
|
d1681e |
+
|
|
|
d1681e |
for (i = 0; i < call_cnt; i++) {
|
|
|
d1681e |
subvol = conf->subvolumes[i];
|
|
|
d1681e |
- if (!subvol)
|
|
|
d1681e |
+ if (!subvol || subvol == mds_subvol)
|
|
|
d1681e |
continue;
|
|
|
d1681e |
-
|
|
|
d1681e |
if (__is_root_gfid (local->stbuf.ia_gfid)) {
|
|
|
d1681e |
ret = syncop_setattr (subvol, &local->loc, &local->stbuf,
|
|
|
d1681e |
(GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE),
|
|
|
d1681e |
NULL, NULL, NULL, NULL);
|
|
|
d1681e |
} else {
|
|
|
d1681e |
- ret = syncop_setattr (subvol, &local->loc, &local->stbuf,
|
|
|
d1681e |
+ ret = syncop_setattr (subvol, &local->loc, &local->mds_stbuf,
|
|
|
d1681e |
(GF_SET_ATTR_UID | GF_SET_ATTR_GID),
|
|
|
d1681e |
NULL, NULL, NULL, NULL);
|
|
|
d1681e |
}
|
|
|
d1681e |
@@ -2324,7 +2795,7 @@ dht_dir_attr_heal (void *data)
|
|
|
d1681e |
if (ret) {
|
|
|
d1681e |
gf_uuid_unparse(local->loc.gfid, gfid);
|
|
|
d1681e |
|
|
|
d1681e |
- gf_msg ("dht", GF_LOG_ERROR, -ret,
|
|
|
d1681e |
+ gf_msg (this->name, GF_LOG_ERROR, -ret,
|
|
|
d1681e |
DHT_MSG_DIR_ATTR_HEAL_FAILED,
|
|
|
d1681e |
"Directory attr heal failed. Failed to set"
|
|
|
d1681e |
" uid/gid on path %s on subvol %s, gfid = %s ",
|
|
|
d1681e |
diff --git a/xlators/cluster/dht/src/dht-shared.c b/xlators/cluster/dht/src/dht-shared.c
|
|
|
d1681e |
index 0373ebf..42daff0 100644
|
|
|
d1681e |
--- a/xlators/cluster/dht/src/dht-shared.c
|
|
|
d1681e |
+++ b/xlators/cluster/dht/src/dht-shared.c
|
|
|
d1681e |
@@ -868,6 +868,7 @@ dht_init (xlator_t *this)
|
|
|
d1681e |
}
|
|
|
d1681e |
|
|
|
d1681e |
GF_OPTION_INIT ("xattr-name", conf->xattr_name, str, err);
|
|
|
d1681e |
+ gf_asprintf (&conf->mds_xattr_key, "%s."DHT_MDS_STR, conf->xattr_name);
|
|
|
d1681e |
gf_asprintf (&conf->link_xattr_name, "%s."DHT_LINKFILE_STR,
|
|
|
d1681e |
conf->xattr_name);
|
|
|
d1681e |
gf_asprintf (&conf->commithash_xattr_name, "%s."DHT_COMMITHASH_STR,
|
|
|
d1681e |
@@ -917,6 +918,7 @@ err:
|
|
|
d1681e |
GF_FREE (conf->xattr_name);
|
|
|
d1681e |
GF_FREE (conf->link_xattr_name);
|
|
|
d1681e |
GF_FREE (conf->wild_xattr_name);
|
|
|
d1681e |
+ GF_FREE (conf->mds_xattr_key);
|
|
|
d1681e |
|
|
|
d1681e |
if (conf->lock_pool)
|
|
|
d1681e |
mem_pool_destroy (conf->lock_pool);
|
|
|
d1681e |
--
|
|
|
d1681e |
1.8.3.1
|
|
|
d1681e |
|