Whamcloud - gitweb
LU-14739 quota: nodemap squashed root cannot bypass quota
[fs/lustre-release.git] / lustre / tests / sanity-sec.sh
index 949e146..9744b9a 100755 (executable)
@@ -52,10 +52,17 @@ ID1=${ID1:-501}
 USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
 USER1=$(getent passwd | grep :$ID1:$ID1: | cut -d: -f1)
 
 USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
 USER1=$(getent passwd | grep :$ID1:$ID1: | cut -d: -f1)
 
-NODEMAP_COUNT=16
-NODEMAP_RANGE_COUNT=3
-NODEMAP_IPADDR_LIST="1 10 64 128 200 250"
-NODEMAP_ID_COUNT=10
+if [ "$SLOW" == "yes" ]; then
+       NODEMAP_COUNT=16
+       NODEMAP_RANGE_COUNT=3
+       NODEMAP_IPADDR_LIST="1 10 64 128 200 250"
+       NODEMAP_ID_COUNT=10
+else
+       NODEMAP_COUNT=3
+       NODEMAP_RANGE_COUNT=2
+       NODEMAP_IPADDR_LIST="1 250"
+       NODEMAP_ID_COUNT=3
+fi
 NODEMAP_MAX_ID=$((ID0 + NODEMAP_ID_COUNT))
 
 [ -z "$USER0" ] &&
 NODEMAP_MAX_ID=$((ID0 + NODEMAP_ID_COUNT))
 
 [ -z "$USER0" ] &&
@@ -161,7 +168,7 @@ test_1() {
        [ $GSS_SUP = 0 ] && skip "without GSS support." && return
 
        rm -rf $DIR/$tdir
        [ $GSS_SUP = 0 ] && skip "without GSS support." && return
 
        rm -rf $DIR/$tdir
-       mkdir -p $DIR/$tdir
+       mkdir_on_mdt0 $DIR/$tdir
 
        chown $USER0 $DIR/$tdir || error "chown (1)"
        $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
 
        chown $USER0 $DIR/$tdir || error "chown (1)"
        $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
@@ -195,12 +202,10 @@ run_test 1 "setuid/gid ============================="
 # as for remote client, the groups of the specified uid on MDT
 # will be obtained by upcall /sbin/l_getidentity and used.
 test_4() {
 # as for remote client, the groups of the specified uid on MDT
 # will be obtained by upcall /sbin/l_getidentity and used.
 test_4() {
-       local server_version=$(lustre_version_code $SINGLEMDS)
-
-       [[ $server_version -ge $(version_code 2.6.93) ]] ||
-       [[ $server_version -ge $(version_code 2.5.35) &&
-          $server_version -lt $(version_code 2.5.50) ]] ||
-               { skip "Need MDS version at least 2.6.93 or 2.5.35"; return; }
+       [[ "$MDS1_VERSION" -ge $(version_code 2.6.93) ]] ||
+       [[ "$MDS1_VERSION" -ge $(version_code 2.5.35) &&
+          "$MDS1_VERSION" -lt $(version_code 2.5.50) ]] ||
+               skip "Need MDS version at least 2.6.93 or 2.5.35"
 
        rm -rf $DIR/$tdir
        mkdir -p $DIR/$tdir
 
        rm -rf $DIR/$tdir
        mkdir -p $DIR/$tdir
@@ -221,7 +226,6 @@ run_test 4 "set supplementary group ==============="
 
 create_nodemaps() {
        local i
 
 create_nodemaps() {
        local i
-       local out
        local rc
 
        squash_id default 99 0
        local rc
 
        squash_id default 99 0
@@ -238,9 +242,10 @@ create_nodemaps() {
                        return $rc
                fi
 
                        return $rc
                fi
 
-               out=$(do_facet mgs $LCTL get_param nodemap.$csum.id)
-               ## This needs to return zero if the following statement is 1
-               [[ $(echo $out | grep -c $csum) == 0 ]] && return 1
+               wait_update_facet --verbose mgs \
+                       "$LCTL get_param nodemap.$csum.id 2>/dev/null | \
+                       grep -c $csum || true" 1 30 ||
+                   return 1
        done
        for (( i = 0; i < NODEMAP_COUNT; i++ )); do
                local csum=${HOSTNAME_CHECKSUM}_${i}
        done
        for (( i = 0; i < NODEMAP_COUNT; i++ )); do
                local csum=${HOSTNAME_CHECKSUM}_${i}
@@ -252,7 +257,6 @@ create_nodemaps() {
 
 delete_nodemaps() {
        local i
 
 delete_nodemaps() {
        local i
-       local out
 
        for ((i = 0; i < NODEMAP_COUNT; i++)); do
                local csum=${HOSTNAME_CHECKSUM}_${i}
 
        for ((i = 0; i < NODEMAP_COUNT; i++)); do
                local csum=${HOSTNAME_CHECKSUM}_${i}
@@ -262,8 +266,10 @@ delete_nodemaps() {
                        return 3
                fi
 
                        return 3
                fi
 
-               out=$(do_facet mgs $LCTL get_param nodemap.$csum.id 2>/dev/null)
-               [[ $(echo $out | grep -c $csum) != 0 ]] && return 1
+               wait_update_facet --verbose mgs \
+                       "$LCTL get_param nodemap.$csum.id 2>/dev/null | \
+                       grep -c $csum || true" 0 30 ||
+                   return 1
        done
        for (( i = 0; i < NODEMAP_COUNT; i++ )); do
                local csum=${HOSTNAME_CHECKSUM}_${i}
        done
        for (( i = 0; i < NODEMAP_COUNT; i++ )); do
                local csum=${HOSTNAME_CHECKSUM}_${i}
@@ -333,9 +339,9 @@ add_idmaps() {
 }
 
 update_idmaps() { #LU-10040
 }
 
 update_idmaps() { #LU-10040
-       [ $(lustre_version_code mgs) -lt $(version_code 2.10.55) ] &&
-               skip "Need MGS >= 2.10.55" &&
-               return
+       [ "$MGS_VERSION" -lt $(version_code 2.10.55) ] &&
+               skip "Need MGS >= 2.10.55"
+
        local csum=${HOSTNAME_CHECKSUM}_0
        local old_id_client=$ID0
        local old_id_fs=$((ID0 + 1))
        local csum=${HOSTNAME_CHECKSUM}_0
        local old_id_client=$ID0
        local old_id_fs=$((ID0 + 1))
@@ -456,9 +462,9 @@ modify_flags() {
 }
 
 squash_id() {
 }
 
 squash_id() {
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
+
        local cmd
 
        cmd[0]="$LCTL nodemap_modify --property squash_uid"
        local cmd
 
        cmd[0]="$LCTL nodemap_modify --property squash_uid"
@@ -469,71 +475,6 @@ squash_id() {
        fi
 }
 
        fi
 }
 
-wait_nm_sync() {
-       local nodemap_name=$1
-       local key=$2
-       local value=$3
-       local opt=$4
-       local proc_param
-       local is_active=$(do_facet mgs $LCTL get_param -n nodemap.active)
-       local max_retries=20
-       local is_sync
-       local out1=""
-       local out2
-       local mgs_ip=$(host_nids_address $mgs_HOST $NETTYPE | cut -d' ' -f1)
-       local i
-
-       if [ "$nodemap_name" == "active" ]; then
-               proc_param="active"
-       elif [ -z "$key" ]; then
-               proc_param=${nodemap_name}
-       else
-               proc_param="${nodemap_name}.${key}"
-       fi
-       if [ "$opt" == "inactive" ]; then
-               # check nm sync even if nodemap is not activated
-               is_active=1
-               opt=""
-       fi
-       (( is_active == 0 )) && [ "$proc_param" != "active" ] && return
-
-       if [ -z "$value" ]; then
-               out1=$(do_facet mgs $LCTL get_param $opt \
-                       nodemap.${proc_param} 2>/dev/null)
-               echo "On MGS ${mgs_ip}, ${proc_param} = $out1"
-       else
-               out1=$value;
-       fi
-
-       # wait up to 10 seconds for other servers to sync with mgs
-       for i in $(seq 1 10); do
-               for node in $(all_server_nodes); do
-                   local node_ip=$(host_nids_address $node $NETTYPE |
-                                   cut -d' ' -f1)
-
-                   is_sync=true
-                   if [ -z "$value" ]; then
-                       [ $node_ip == $mgs_ip ] && continue
-                   fi
-
-                   out2=$(do_node $node_ip $LCTL get_param $opt \
-                                  nodemap.$proc_param 2>/dev/null)
-                   echo "On $node ${node_ip}, ${proc_param} = $out2"
-                   [ "$out1" != "$out2" ] && is_sync=false && break
-               done
-               $is_sync && break
-               sleep 1
-       done
-       if ! $is_sync; then
-               echo MGS
-               echo $out1
-               echo OTHER - IP: $node_ip
-               echo $out2
-               error "mgs and $nodemap_name ${key} mismatch, $i attempts"
-       fi
-       echo "waited $((i - 1)) seconds for sync"
-}
-
 # ensure that the squash defaults are the expected defaults
 squash_id default 99 0
 wait_nm_sync default squash_uid '' inactive
 # ensure that the squash defaults are the expected defaults
 squash_id default 99 0
 wait_nm_sync default squash_uid '' inactive
@@ -685,18 +626,17 @@ test_idmap() {
 test_7() {
        local rc
 
 test_7() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        create_nodemaps
        rc=$?
 
        create_nodemaps
        rc=$?
-       [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
+       [[ $rc != 0 ]] && error "nodemap_add failed with $rc"
 
        delete_nodemaps
        rc=$?
 
        delete_nodemaps
        rc=$?
-       [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 2
+       [[ $rc != 0 ]] && error "nodemap_del failed with $rc"
 
        return 0
 }
 
        return 0
 }
@@ -705,10 +645,9 @@ run_test 7 "nodemap create and delete"
 test_8() {
        local rc
 
 test_8() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        # Set up nodemaps
 
 
        # Set up nodemaps
 
@@ -736,10 +675,9 @@ test_9() {
        local i
        local rc
 
        local i
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -774,10 +712,9 @@ run_test 9 "nodemap range add"
 test_10a() {
        local rc
 
 test_10a() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -819,8 +756,8 @@ test_10a() {
 run_test 10a "nodemap reject duplicate ranges"
 
 test_10b() {
 run_test 10a "nodemap reject duplicate ranges"
 
 test_10b() {
-       [ $(lustre_version_code mgs) -lt $(version_code 2.10.53) ] &&
-               skip "Need MGS >= 2.10.53" && return
+       [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] &&
+               skip "Need MGS >= 2.10.53"
 
        local nm1="nodemap1"
        local nm2="nodemap2"
 
        local nm1="nodemap1"
        local nm2="nodemap2"
@@ -847,8 +784,8 @@ test_10b() {
 run_test 10b "delete range from the correct nodemap"
 
 test_10c() { #LU-8912
 run_test 10b "delete range from the correct nodemap"
 
 test_10c() { #LU-8912
-       [ $(lustre_version_code mgs) -lt $(version_code 2.10.57) ] &&
-               skip "Need MGS >= 2.10.57" && return
+       [ "$MGS_VERSION" -lt $(version_code 2.10.57) ] &&
+               skip "Need MGS >= 2.10.57"
 
        local nm="nodemap_lu8912"
        local nid_range="10.210.[32-47].[0-255]@o2ib3"
 
        local nm="nodemap_lu8912"
        local nid_range="10.210.[32-47].[0-255]@o2ib3"
@@ -877,8 +814,8 @@ test_10c() { #LU-8912
 run_test 10c "verfify contiguous range support"
 
 test_10d() { #LU-8913
 run_test 10c "verfify contiguous range support"
 
 test_10d() { #LU-8913
-       [ $(lustre_version_code mgs) -lt $(version_code 2.10.59) ] &&
-               skip "Need MGS >= 2.10.59" && return
+       [ "$MGS_VERSION" -lt $(version_code 2.10.59) ] &&
+               skip "Need MGS >= 2.10.59"
 
        local nm="nodemap_lu8913"
        local nid_range="*@o2ib3"
 
        local nm="nodemap_lu8913"
        local nid_range="*@o2ib3"
@@ -909,10 +846,9 @@ run_test 10d "verfify nodemap range format '*@<net>' support"
 test_11() {
        local rc
 
 test_11() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -939,10 +875,9 @@ run_test 11 "nodemap modify"
 test_12() {
        local rc
 
 test_12() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -977,10 +912,9 @@ run_test 12 "nodemap set squash ids"
 test_13() {
        local rc
 
 test_13() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -1020,10 +954,9 @@ run_test 13 "test nids"
 test_14() {
        local rc
 
 test_14() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -1055,10 +988,9 @@ run_test 14 "test default nodemap nid lookup"
 test_15() {
        local rc
 
 test_15() {
        local rc
 
-       remote_mgs_nodsh && skip "remote MGS with nodsh" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
-               return
+       remote_mgs_nodsh && skip "remote MGS with nodsh"
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
 
        rc=0
        create_nodemaps
 
        rc=0
        create_nodemaps
@@ -1451,18 +1383,26 @@ test_fops_chmod_dir() {
 test_fops() {
        local mapmode="$1"
        local single_client="$2"
 test_fops() {
        local mapmode="$1"
        local single_client="$2"
-       local client_user_list=([0]="0 $((IDBASE+3)) $((IDBASE+4))"
-                               [1]="0 $((IDBASE+5)) $((IDBASE+6))")
+       local client_user_list=([0]="0 $((IDBASE+3))"
+                               [1]="0 $((IDBASE+5))")
+       local mds_users="-1 0"
        local mds_i
        local rc=0
        local mds_i
        local rc=0
-       local perm_bit_list="0 3 $((0300)) $((0303))"
+       local perm_bit_list="3 $((0300))"
        # SLOW tests 000-007, 010-070, 100-700 (octal modes)
        # SLOW tests 000-007, 010-070, 100-700 (octal modes)
-       [ "$SLOW" == "yes" ] &&
+       if [ "$SLOW" == "yes" ]; then
                perm_bit_list="0 $(seq 1 7) $(seq 8 8 63) $(seq 64 64 511) \
                               $((0303))"
                perm_bit_list="0 $(seq 1 7) $(seq 8 8 63) $(seq 64 64 511) \
                               $((0303))"
+               client_user_list=([0]="0 $((IDBASE+3)) $((IDBASE+4))"
+                                 [1]="0 $((IDBASE+5)) $((IDBASE+6))")
+               mds_users="-1 0 1 2"
+       fi
 
 
+       # force single_client to speed up test
+       [ "$SLOW" == "yes" ] ||
+               single_client=1
        # step through mds users. -1 means root
        # step through mds users. -1 means root
-       for mds_i in -1 0 1 2; do
+       for mds_i in $mds_users; do
                local user=$((mds_i + IDBASE))
                local client
                local x
                local user=$((mds_i + IDBASE))
                local client
                local x
@@ -1503,8 +1443,8 @@ test_fops() {
 
 nodemap_version_check () {
        remote_mgs_nodsh && skip "remote MGS with nodsh" && return 1
 
 nodemap_version_check () {
        remote_mgs_nodsh && skip "remote MGS with nodsh" && return 1
-       [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
-               skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
+       [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
+               skip "No nodemap on $MGS_VERSION MGS < 2.5.53" &&
                return 1
        return 0
 }
                return 1
        return 0
 }
@@ -1581,7 +1521,7 @@ run_test 16 "test nodemap all_off fileops"
 
 test_17() {
        if $SHARED_KEY &&
 
 test_17() {
        if $SHARED_KEY &&
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ]; then
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
                skip "Need MDS >= 2.11.55"
        fi
 
                skip "Need MDS >= 2.11.55"
        fi
 
@@ -1597,7 +1537,7 @@ run_test 17 "test nodemap trusted_noadmin fileops"
 
 test_18() {
        if $SHARED_KEY &&
 
 test_18() {
        if $SHARED_KEY &&
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ]; then
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
                skip "Need MDS >= 2.11.55"
        fi
 
                skip "Need MDS >= 2.11.55"
        fi
 
@@ -1613,7 +1553,7 @@ run_test 18 "test nodemap mapped_noadmin fileops"
 
 test_19() {
        if $SHARED_KEY &&
 
 test_19() {
        if $SHARED_KEY &&
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ]; then
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
                skip "Need MDS >= 2.11.55"
        fi
 
                skip "Need MDS >= 2.11.55"
        fi
 
@@ -1629,7 +1569,7 @@ run_test 19 "test nodemap trusted_admin fileops"
 
 test_20() {
        if $SHARED_KEY &&
 
 test_20() {
        if $SHARED_KEY &&
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ]; then
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
                skip "Need MDS >= 2.11.55"
        fi
 
                skip "Need MDS >= 2.11.55"
        fi
 
@@ -1645,7 +1585,7 @@ run_test 20 "test nodemap mapped_admin fileops"
 
 test_21() {
        if $SHARED_KEY &&
 
 test_21() {
        if $SHARED_KEY &&
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ]; then
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
                skip "Need MDS >= 2.11.55"
        fi
 
                skip "Need MDS >= 2.11.55"
        fi
 
@@ -1672,7 +1612,7 @@ run_test 21 "test nodemap mapped_trusted_noadmin fileops"
 
 test_22() {
        if $SHARED_KEY &&
 
 test_22() {
        if $SHARED_KEY &&
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ]; then
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
                skip "Need MDS >= 2.11.55"
        fi
 
                skip "Need MDS >= 2.11.55"
        fi
 
@@ -1816,9 +1756,9 @@ test_23a() {
 run_test 23a "test mapped regular ACLs"
 
 test_23b() { #LU-9929
 run_test 23a "test mapped regular ACLs"
 
 test_23b() { #LU-9929
-       [ $num_clients -lt 2 ] && skip "Need 2 clients at least" && return
-       [ $(lustre_version_code mgs) -lt $(version_code 2.10.53) ] &&
-               skip "Need MGS >= 2.10.53" && return
+       [ $num_clients -lt 2 ] && skip "Need 2 clients at least"
+       [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] &&
+               skip "Need MGS >= 2.10.53"
 
        export SK_UNIQUE_NM=true
        nodemap_test_setup
 
        export SK_UNIQUE_NM=true
        nodemap_test_setup
@@ -2059,8 +1999,8 @@ nodemap_exercise_fileset() {
 }
 
 test_27a() {
 }
 
 test_27a() {
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.50) ] &&
-               skip "Need MDS >= 2.11.50" && return
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
+               skip "Need MDS >= 2.11.50"
 
        for nm in "default" "c0"; do
                local subdir="subdir_${nm}"
 
        for nm in "default" "c0"; do
                local subdir="subdir_${nm}"
@@ -2078,9 +2018,9 @@ test_27a() {
 run_test 27a "test fileset in various nodemaps"
 
 test_27b() { #LU-10703
 run_test 27a "test fileset in various nodemaps"
 
 test_27b() { #LU-10703
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.50) ] &&
-               skip "Need MDS >= 2.11.50" && return
-       [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
+               skip "Need MDS >= 2.11.50"
+       [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs"
 
        nodemap_test_setup
        trap nodemap_test_cleanup EXIT
 
        nodemap_test_setup
        trap nodemap_test_cleanup EXIT
@@ -2157,22 +2097,26 @@ test_29() {
        touch $DIR/$tdir/$tfile || error "touch"
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount clients"
        touch $DIR/$tdir/$tfile || error "touch"
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount clients"
-       keyctl show | awk '/lustre/ { print $1 }' |
-               xargs -IX keyctl unlink X
+       do_node ${clients_arr[0]} "keyctl show |
+               awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
        OLD_SK_PATH=$SK_PATH
        export SK_PATH=/dev/null
        if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
                export SK_PATH=$OLD_SK_PATH
        OLD_SK_PATH=$SK_PATH
        export SK_PATH=/dev/null
        if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
                export SK_PATH=$OLD_SK_PATH
-               if [ -e $DIR/$tdir/$tfile ]; then
+               do_node ${clients_arr[0]} "ls $DIR/$tdir/$tfile"
+               if [ $? -eq 0 ]; then
                        error "able to mount and read without key"
                else
                        error "able to mount without key"
                fi
        else
                export SK_PATH=$OLD_SK_PATH
                        error "able to mount and read without key"
                else
                        error "able to mount without key"
                fi
        else
                export SK_PATH=$OLD_SK_PATH
-               keyctl show | awk '/lustre/ { print $1 }' |
-                       xargs -IX keyctl unlink X
+               do_node ${clients_arr[0]} "keyctl show |
+                       awk '/lustre/ { print \\\$1 }' |
+                       xargs -IX keyctl unlink X"
        fi
        fi
+       zconf_mount_clients ${clients_arr[0]} $MOUNT ||
+               error "unable to mount clients"
 }
 run_test 29 "check for missing shared key"
 
 }
 run_test 29 "check for missing shared key"
 
@@ -2188,28 +2132,71 @@ test_30() {
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount clients"
        # unload keys from ring
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount clients"
        # unload keys from ring
-       keyctl show | awk '/lustre/ { print $1 }' |
-               xargs -IX keyctl unlink X
-       # invalidate the key with bogus filesystem name
-       lgss_sk -w $SK_PATH/$FSNAME-bogus.key -f $FSNAME.bogus \
-               -t client -d /dev/urandom || error "lgss_sk failed (1)"
+       do_node ${clients_arr[0]} "keyctl show |
+               awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
+       # generate key with bogus filesystem name
+       do_node ${clients_arr[0]} "lgss_sk -w $SK_PATH/$FSNAME-bogus.key \
+               -f $FSNAME.bogus -t client -d /dev/urandom" ||
+               error "lgss_sk failed (1)"
        do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx"
        OLD_SK_PATH=$SK_PATH
        export SK_PATH=$SK_PATH/$FSNAME-bogus.key
        if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
                SK_PATH=$OLD_SK_PATH
        do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx"
        OLD_SK_PATH=$SK_PATH
        export SK_PATH=$SK_PATH/$FSNAME-bogus.key
        if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
                SK_PATH=$OLD_SK_PATH
-               if [ -a $DIR/$tdir/$tdir.out ]; then
+               do_node ${clients_arr[0]} "ls $DIR/$tdir/$tdir.out"
+               if [ $? -eq 0 ]; then
                        error "mount and read file with invalid key"
                else
                        error "mount with invalid key"
                fi
        fi
                        error "mount and read file with invalid key"
                else
                        error "mount with invalid key"
                fi
        fi
-       SK_PATH=$OLD_SK_PATH
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount clients"
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount clients"
+       # unload keys from ring
+       do_node ${clients_arr[0]} "keyctl show |
+               awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
+       rm -f $SK_PATH
+       SK_PATH=$OLD_SK_PATH
+       zconf_mount_clients ${clients_arr[0]} $MOUNT ||
+               error "unable to mount clients"
 }
 run_test 30 "check for invalid shared key"
 
 }
 run_test 30 "check for invalid shared key"
 
+basic_ios() {
+       local flvr=$1
+
+       mkdir -p $DIR/$tdir || error "mkdir $flvr"
+       touch $DIR/$tdir/f0 || error "touch $flvr"
+       ls $DIR/$tdir || error "ls $flvr"
+       dd if=/dev/zero of=$DIR/$tdir/f0 conv=fsync bs=1M count=10 \
+               >& /dev/null || error "dd $flvr"
+       rm -f $DIR/$tdir/f0 || error "rm $flvr"
+       rmdir $DIR/$tdir || error "rmdir $flvr"
+
+       sync ; sync
+       echo 3 > /proc/sys/vm/drop_caches
+}
+
+test_30b() {
+       local save_flvr=$SK_FLAVOR
+
+       if ! $SHARED_KEY; then
+               skip "need shared key feature for this test"
+       fi
+
+       stack_trap restore_to_default_flavor EXIT
+
+       for flvr in skn ska ski skpi; do
+               # set flavor
+               SK_FLAVOR=$flvr
+               restore_to_default_flavor || error "cannot set $flvr flavor"
+               SK_FLAVOR=$save_flvr
+
+               basic_ios $flvr
+       done
+}
+run_test 30b "basic test of all different SSK flavors"
+
 cleanup_31() {
        # unmount client
        zconf_umount $HOSTNAME $MOUNT || error "unable to umount client"
 cleanup_31() {
        # unmount client
        zconf_umount $HOSTNAME $MOUNT || error "unable to umount client"
@@ -2586,6 +2573,1608 @@ test_34() {
 }
 run_test 34 "deny_unknown on default nodemap"
 
 }
 run_test 34 "deny_unknown on default nodemap"
 
+test_35() {
+       [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.13.50) ] ||
+               skip "Need MDS >= 2.13.50"
+
+       # activate changelogs
+       changelog_register || error "changelog_register failed"
+       local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
+       changelog_users $SINGLEMDS | grep -q $cl_user ||
+               error "User $cl_user not found in changelog_users"
+       changelog_chmask ALL
+
+       # do some IOs
+       mkdir $DIR/$tdir || error "failed to mkdir $tdir"
+       touch $DIR/$tdir/$tfile || error "failed to touch $tfile"
+
+       # access changelogs with root
+       changelog_dump || error "failed to dump changelogs"
+       changelog_clear 0 || error "failed to clear changelogs"
+
+       # put clients in non-admin nodemap
+       nodemap_test_setup
+       stack_trap nodemap_test_cleanup EXIT
+       for i in $(seq 0 $((num_clients-1))); do
+               do_facet mgs $LCTL nodemap_modify --name c${i} \
+                        --property admin --value 0
+       done
+       for i in $(seq 0 $((num_clients-1))); do
+               wait_nm_sync c${i} admin_nodemap
+       done
+
+       # access with mapped root
+       changelog_dump && error "dump changelogs should have failed"
+       changelog_clear 0 && error "clear changelogs should have failed"
+
+       exit 0
+}
+run_test 35 "Check permissions when accessing changelogs"
+
+setup_for_enc_tests() {
+       # remount client with test_dummy_encryption option
+       if is_mounted $MOUNT; then
+               umount_client $MOUNT || error "umount $MOUNT failed"
+       fi
+       mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
+               error "mount with '-o test_dummy_encryption' failed"
+
+       # this directory will be encrypted, because of dummy mode
+       mkdir $DIR/$tdir
+}
+
+cleanup_for_enc_tests() {
+       # remount client normally
+       if is_mounted $MOUNT; then
+               umount_client $MOUNT || error "umount $MOUNT failed"
+       fi
+       mount_client $MOUNT ${MOUNT_OPTS} ||
+               error "remount failed"
+
+       if is_mounted $MOUNT2; then
+               umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+       fi
+       if [ "$MOUNT_2" ]; then
+               mount_client $MOUNT2 ${MOUNT_OPTS} ||
+                       error "remount failed"
+       fi
+}
+
+cleanup_nodemap_after_enc_tests() {
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property forbid_encryption --value 0
+       wait_nm_sync default forbid_encryption
+       do_facet mgs $LCTL nodemap_activate 0
+       wait_nm_sync active
+}
+
+test_36() {
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+
+       # first make sure it is possible to enable encryption
+       # when nodemap is not active
+       setup_for_enc_tests
+       rmdir $DIR/$tdir
+       umount_client $MOUNT || error "umount $MOUNT failed (1)"
+
+       # then activate nodemap, and retry
+       # should succeed as encryption is not forbidden on default nodemap
+       # by default
+       stack_trap cleanup_nodemap_after_enc_tests EXIT
+       do_facet mgs $LCTL nodemap_activate 1
+       wait_nm_sync active
+       forbid=$(do_facet mgs lctl get_param -n nodemap.default.forbid_encryption)
+       [ $forbid -eq 0 ] || error "wrong default value for forbid_encryption"
+       mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
+               error "mount '-o test_dummy_encryption' failed with default"
+       umount_client $MOUNT || error "umount $MOUNT failed (2)"
+
+       # then forbid encryption, and retry
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property forbid_encryption --value 1
+       wait_nm_sync default forbid_encryption
+       mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption &&
+               error "mount '-o test_dummy_encryption' should have failed"
+       return 0
+}
+run_test 36 "control if clients can use encryption"
+
+test_37() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local objdump=$TMP/objdump
+       local objid
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       [ "$ost1_FSTYPE" = ldiskfs ] || skip "ldiskfs only test (using debugfs)"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       # write a few bytes in file
+       echo "abc" > $tmpfile
+       $LFS setstripe -c1 -i0 $testfile
+       dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
+       do_facet ost1 "sync; sync"
+
+       # check that content on ost is encrypted
+       objid=$($LFS getstripe $testfile | awk '/obdidx/{getline; print $2}')
+       do_facet ost1 "$DEBUGFS -c -R 'cat O/0/d$(($objid % 32))/$objid' \
+                $(ostdevname 1)" > $objdump
+       cmp -s $objdump $tmpfile &&
+               error "file $testfile is not encrypted on ost"
+
+       # check that in-memory representation of file is correct
+       cmp -bl ${tmpfile} ${testfile} ||
+               error "file $testfile is corrupted in memory"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl ${tmpfile} ${testfile} ||
+               error "file $testfile is corrupted on server"
+
+       rm -f $tmpfile $objdump
+}
+run_test 37 "simple encrypted file"
+
+test_38() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local objid
+       local blksz
+       local srvsz=0
+       local filesz
+       local bsize
+       local pagesz=$(getconf PAGE_SIZE)
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       # get block size on ost
+       blksz=$($LCTL get_param osc.$FSNAME*.import |
+               awk '/grant_block_size:/ { print $2; exit; }')
+       # write a few bytes in file at offset $blksz
+       echo "abc" > $tmpfile
+       $LFS setstripe -c1 -i0 $testfile
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$blksz \
+               oflag=seek_bytes conv=fsync
+
+       blksz=$(($blksz > $pagesz ? $blksz : $pagesz))
+       # check that in-memory representation of file is correct
+       bsize=$(stat --format=%B $testfile)
+       filesz=$(stat --format=%b $testfile)
+       filesz=$((filesz*bsize))
+       [ $filesz -le $blksz ] ||
+               error "file $testfile is $filesz long in memory"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       bsize=$(stat --format=%B $testfile)
+       filesz=$(stat --format=%b $testfile)
+       filesz=$((filesz*bsize))
+       [ $filesz -le $blksz ] ||
+               error "file $testfile is $filesz long on server"
+
+       rm -f $tmpfile
+}
+run_test 38 "encrypted file with hole"
+
+test_39() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       # write a few bytes in file
+       echo "abc" > $tmpfile
+       $LFS setstripe -c1 -i0 $testfile
+       dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
+
+       # write a few more bytes in the same page
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=1024 oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=1024 oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server"
+
+       rm -f $tmpfile
+}
+run_test 39 "rewrite data in already encrypted page"
+
+test_40() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local tmpfile2=$TMP/abc2
+       local seek
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       # write a few bytes in file
+       echo "abc" > $tmpfile
+       $LFS setstripe -c1 -i0 $testfile
+       dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory (1)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server (1)"
+
+       # write a few other bytes in same page
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=256 oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=256 oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory (2)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server (2)"
+
+       rm -f $testfile $tmpfile
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # write a few bytes in file, at end of first page
+       echo "abc" > $tmpfile
+       $LFS setstripe -c1 -i0 $testfile
+       seek=$(getconf PAGESIZE)
+       seek=$((seek - 4))
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # write a few other bytes at beginning of first page
+       dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync,notrunc
+
+       dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory (3)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server (3)"
+
+       rm -f $testfile $tmpfile
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # write a few bytes in file, at beginning of second page
+       echo "abc" > $tmpfile
+       $LFS setstripe -c1 -i0 $testfile
+       seek=$(getconf PAGESIZE)
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+       dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # write a few other bytes at end of first page
+       seek=$((seek - 4))
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+       dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile2 $testfile ||
+               error "file $testfile is corrupted in memory (4)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile2 $testfile ||
+               error "file $testfile is corrupted on server (4)"
+
+       rm -f $testfile $tmpfile $tmpfile2
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # write a few bytes in file, at beginning of first stripe
+       echo "abc" > $tmpfile
+       $LFS setstripe -S 256k -c2 $testfile
+       dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync,notrunc
+
+       # write a few other bytes, at beginning of second stripe
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=262144 oflag=seek_bytes \
+               conv=fsync,notrunc
+       dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=262144 oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory (5)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server (5)"
+
+       rm -f $tmpfile
+}
+run_test 40 "exercise size of encrypted file"
+
+test_41() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local tmpfile2=$TMP/abc2
+       local seek
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       echo "abc" > $tmpfile
+       seek=$(getconf PAGESIZE)
+       seek=$((seek - 204))
+       dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync
+       seek=$(getconf PAGESIZE)
+       seek=$((seek + 1092))
+       dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # write a few bytes in file
+       $LFS setstripe -c1 -i0 -S 256k $testfile
+       seek=$(getconf PAGESIZE)
+       seek=$((seek - 204))
+       #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
+       do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync &
+
+       sleep 5
+       # write a few other bytes, at a different offset
+       seek=$(getconf PAGESIZE)
+       seek=$((seek + 1092))
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc &
+       wait
+       do_facet ost1 "$LCTL set_param fail_loc=0x0"
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile2 $testfile ||
+               error "file $testfile is corrupted in memory (1)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile2 $testfile ||
+               error "file $testfile is corrupted on server (1)"
+
+       rm -f $tmpfile $tmpfile2
+}
+run_test 41 "test race on encrypted file size (1)"
+
+test_42() {
+       local testfile=$DIR/$tdir/$tfile
+       local testfile2=$DIR2/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local tmpfile2=$TMP/abc2
+       local pagesz=$(getconf PAGESIZE)
+       local seek
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       if is_mounted $MOUNT2; then
+               umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+       fi
+       mount_client $MOUNT2 ${MOUNT_OPTS},test_dummy_encryption ||
+               error "mount2 with '-o test_dummy_encryption' failed"
+
+       # create file by writting one whole page
+       $LFS setstripe -c1 -i0 -S 256k $testfile
+       dd if=/dev/zero of=$testfile bs=$pagesz count=1 conv=fsync
+
+       # read file from 2nd mount point
+       cat $testfile2 > /dev/null
+
+       echo "abc" > $tmpfile
+       dd if=/dev/zero of=$tmpfile2 bs=$pagesz count=1 conv=fsync
+       seek=$((2*pagesz - 204))
+       dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+       seek=$((2*pagesz + 1092))
+       dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+
+       # write a few bytes in file from 1st mount point
+       seek=$((2*pagesz - 204))
+       #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
+       do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
+       dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc &
+
+       sleep 5
+       # write a few other bytes, at a different offset from 2nd mount point
+       seek=$((2*pagesz + 1092))
+       dd if=$tmpfile of=$testfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc &
+       wait
+       do_facet ost1 "$LCTL set_param fail_loc=0x0"
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile2 $testfile ||
+               error "file $testfile is corrupted in memory (1)"
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile2 $testfile2 ||
+               error "file $testfile is corrupted in memory (2)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile2 $testfile ||
+               error "file $testfile is corrupted on server (1)"
+
+       rm -f $tmpfile $tmpfile2
+}
+run_test 42 "test race on encrypted file size (2)"
+
+test_43() {
+       local testfile=$DIR/$tdir/$tfile
+       local testfile2=$DIR2/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local tmpfile2=$TMP/abc2
+       local resfile=$TMP/res
+       local pagesz=$(getconf PAGESIZE)
+       local seek
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       if is_mounted $MOUNT2; then
+               umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+       fi
+       mount_client $MOUNT2 ${MOUNT_OPTS},test_dummy_encryption ||
+               error "mount2 with '-o test_dummy_encryption' failed"
+
+       # create file
+       tr '\0' '1' < /dev/zero |
+               dd of=$tmpfile bs=1 count=$pagesz conv=fsync
+       $LFS setstripe -c1 -i0 -S 256k $testfile
+       cp $tmpfile $testfile
+
+       # read file from 2nd mount point
+       cat $testfile2 > /dev/null
+
+       # write a few bytes in file from 1st mount point
+       echo "abc" > $tmpfile2
+       seek=$((2*pagesz - 204))
+       #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
+       do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
+       dd if=$tmpfile2 of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc &
+
+       sleep 5
+       # read file from 2nd mount point
+       dd if=$testfile2 of=$resfile bs=$pagesz count=1 conv=fsync,notrunc
+       cmp -bl $tmpfile $resfile ||
+               error "file $testfile is corrupted in memory (1)"
+
+       wait
+       do_facet ost1 "$LCTL set_param fail_loc=0x0"
+
+       # check that in-memory representation of file is correct
+       dd if=$tmpfile2 of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+       cmp -bl $tmpfile $testfile2 ||
+               error "file $testfile is corrupted in memory (2)"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server (1)"
+
+       rm -f $tmpfile $tmpfile2
+}
+run_test 43 "test race on encrypted file size (3)"
+
+test_44() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local resfile=$TMP/resfile
+       local pagesz=$(getconf PAGESIZE)
+       local respage
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       which vmtouch || skip "This test needs vmtouch utility"
+
+       # Direct I/O is now supported on encrypted files.
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       $LFS setstripe -c1 -i0 $testfile
+       dd if=/dev/urandom of=$tmpfile bs=$pagesz count=2 conv=fsync
+       dd if=$tmpfile of=$testfile bs=$pagesz count=2 oflag=direct ||
+               error "could not write to file with O_DIRECT (1)"
+
+       respage=$(vmtouch $testfile | awk '/Resident Pages:/ {print $3}')
+       [ "$respage" == "0/2" ] ||
+               error "write to enc file fell back to buffered IO"
+
+       cancel_lru_locks
+
+       dd if=$testfile of=$resfile bs=$pagesz count=2 iflag=direct ||
+               error "could not read from file with O_DIRECT (1)"
+
+       respage=$(vmtouch $testfile | awk '/Resident Pages:/ {print $3}')
+       [ "$respage" == "0/2" ] ||
+               error "read from enc file fell back to buffered IO"
+
+       cmp -bl $tmpfile $resfile ||
+               error "file $testfile is corrupted (1)"
+
+       rm -f $resfile
+
+       $TRUNCATE $tmpfile $pagesz
+       dd if=$tmpfile of=$testfile bs=$pagesz count=1 seek=13 oflag=direct ||
+               error "could not write to file with O_DIRECT (2)"
+
+       cancel_lru_locks
+
+       dd if=$testfile of=$resfile bs=$pagesz count=1 skip=13 iflag=direct ||
+               error "could not read from file with O_DIRECT (2)"
+       cmp -bl $tmpfile $resfile ||
+               error "file $testfile is corrupted (2)"
+
+       rm -f $testfile $resfile
+       $LFS setstripe -c1 -i0 $testfile
+
+       $TRUNCATE $tmpfile $((pagesz/2 - 5))
+       cp $tmpfile $testfile
+
+       cancel_lru_locks
+
+       dd if=$testfile of=$resfile bs=$pagesz count=1 iflag=direct ||
+               error "could not read from file with O_DIRECT (3)"
+       cmp -bl $tmpfile $resfile ||
+               error "file $testfile is corrupted (3)"
+
+       rm -f $tmpfile $resfile
+}
+run_test 44 "encrypted file access semantics: direct IO"
+
+test_45() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/junk
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       $LFS setstripe -c1 -i0 $testfile
+       dd if=/dev/zero of=$testfile bs=512K count=1
+       $MULTIOP $testfile OSMRUc || error "$MULTIOP $testfile failed (1)"
+       $MULTIOP $testfile OSMWUc || error "$MULTIOP $testfile failed (2)"
+
+       dd if=/dev/zero of=$tmpfile bs=512K count=1
+       $MULTIOP $tmpfile OSMWUc || error "$MULTIOP $tmpfile failed"
+       $MMAP_CAT $tmpfile > ${tmpfile}2
+
+       cancel_lru_locks
+
+       $MULTIOP $testfile OSMRUc
+       $MMAP_CAT $testfile > ${testfile}2
+       cmp -bl ${tmpfile}2 ${testfile}2 ||
+               error "file $testfile is corrupted"
+
+       rm -f $tmpfile ${tmpfile}2
+}
+run_test 45 "encrypted file access semantics: MMAP"
+
+test_46() {
+       local testdir=$DIR/$tdir/mydir
+       local testfile=$testdir/myfile
+       local lsfile=$TMP/lsfile
+       local scrambleddir
+       local scrambledfile
+
+       local testfile2=$DIR/$tdir/${tfile}.2
+       local tmpfile=$DIR/junk
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       touch $DIR/onefile
+       touch $DIR/$tdir/$tfile
+       mkdir $testdir
+       echo test > $testfile
+       sync ; echo 3 > /proc/sys/vm/drop_caches
+
+       # remove fscrypt key from keyring
+       keyctl revoke $(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
+       keyctl reap
+
+       scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
+       ls -1 $scrambleddir > $lsfile || error "ls $testdir failed"
+
+       scrambledfile=$scrambleddir/$(head -n 1 $lsfile)
+       stat $scrambledfile || error "stat $scrambledfile failed"
+       rm -f $lsfile
+
+       cat $scrambledfile && error "cat $scrambledfile should have failed"
+
+       touch $scrambleddir/otherfile &&
+               error "touch otherfile should have failed"
+       ls $scrambleddir/otherfile && error "otherfile should not exist"
+       mkdir $scrambleddir/otherdir &&
+               error "mkdir otherdir should have failed"
+       ls -d $scrambleddir/otherdir && error "otherdir should not exist"
+
+       rm -f $scrambledfile || error "rm $scrambledfile failed"
+       rmdir $scrambleddir || error "rmdir $scrambleddir failed"
+
+       rm -f $DIR/onefile
+}
+run_test 46 "encrypted file access semantics without key"
+
+test_47() {
+       local testfile=$DIR/$tdir/$tfile
+       local testfile2=$DIR/$tdir/${tfile}.2
+       local tmpfile=$DIR/junk
+       local scrambleddir
+       local scrambledfile
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       dd if=/dev/zero of=$tmpfile bs=512K count=1
+       mrename $tmpfile $testfile &&
+               error "rename from unencrypted to encrypted dir should fail"
+
+       ln $tmpfile $testfile &&
+               error "link from unencrypted to encrypted dir should fail"
+
+       cp $tmpfile $testfile ||
+               error "cp from unencrypted to encrypted dir should succeed"
+       rm -f $tmpfile
+
+       mrename $testfile $testfile2 ||
+               error "rename from within encrypted dir should succeed"
+
+       ln $testfile2 $testfile ||
+               error "link from within encrypted dir should succeed"
+       rm -f $testfile
+
+       ln $testfile2 $tmpfile ||
+               error "link from encrypted to unencrypted dir should succeed"
+       rm -f $tmpfile
+
+       # check we are limited in the number of hard links
+       # we can create for encrypted files, to what can fit into LinkEA
+       for i in $(seq 1 160); do
+               ln $testfile2 ${testfile}_$i || break
+       done
+       [ $i -lt 160 ] || error "hard link $i should fail"
+
+       mrename $testfile2 $tmpfile &&
+               error "rename from encrypted to unencrypted dir should fail"
+       touch $tmpfile
+
+       dd if=/dev/zero of=$testfile bs=512K count=1
+       mkdir $DIR/$tdir/mydir
+       sync ; echo 3 > /proc/sys/vm/drop_caches
+
+       # remove fscrypt key from keyring
+       keyctl revoke $(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
+       keyctl reap
+
+       scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
+       scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -type f)
+       ln $scrambledfile $scrambleddir/linkfile &&
+               error "ln linkfile should have failed"
+       mrename $scrambledfile $DIR/onefile2 &&
+               error "mrename from $scrambledfile should have failed"
+       touch $DIR/onefile
+       mrename $DIR/onefile $scrambleddir/otherfile &&
+               error "mrename to $scrambleddir should have failed"
+
+       rm -f $tmpfile $DIR/onefile
+}
+run_test 47 "encrypted file access semantics: rename/link"
+
+test_48a() {
+       local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/111
+       local tmpfile2=$TMP/abc
+       local pagesz=$(getconf PAGESIZE)
+       local sz
+       local seek
+       local scrambledfile
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       # create file, 4 x PAGE_SIZE long
+       tr '\0' '1' < /dev/zero |
+               dd of=$tmpfile bs=1 count=4x$pagesz conv=fsync
+       $LFS setstripe -c1 -i0 $testfile
+       cp $tmpfile $testfile
+       echo "abc" > $tmpfile2
+
+       # decrease size: truncate to PAGE_SIZE
+       $TRUNCATE $tmpfile $pagesz
+       $TRUNCATE $testfile $pagesz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (1)"
+
+       # increase size: truncate to 2 x PAGE_SIZE
+       sz=$((pagesz*2))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (2)"
+
+       # write in 2nd page
+       seek=$((pagesz+100))
+       dd if=$tmpfile2 of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+       dd if=$tmpfile2 of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
+               conv=fsync,notrunc
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (3)"
+
+       # truncate to PAGE_SIZE / 2
+       sz=$((pagesz/2))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (4)"
+
+       # lockless truncate should be turned into regular truncate for enc file
+       save_lustre_params client "osc.*.lockless_truncate" > $save
+       # restore lockless_truncate default values on exit
+       stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       lctl set_param -n osc.*.lockless_truncate 1
+       cancel_lru_locks osc
+       clear_stats osc.*.osc_stats
+       $TRUNCATE $testfile 8000000 || error "truncate failed (1)"
+       [ $(calc_stats osc.*.osc_stats lockless_truncate) -eq 0 ] ||
+               error "lockless truncate should be turned into regular truncate"
+       lctl set_param -n osc.*.lockless_truncate 0
+
+       # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16
+       sz=$((sz-7))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (5)"
+
+       # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16
+       sz=$((sz+18))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (6)"
+
+       # truncate to a larger, non-multiple of PAGE_SIZE, in a different page
+       sz=$((sz+pagesz+30))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (7)"
+
+       sync ; echo 3 > /proc/sys/vm/drop_caches
+
+       # remove fscrypt key from keyring
+       keyctl revoke $(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
+       keyctl reap
+
+       scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -type f)
+       $TRUNCATE $scrambledfile 0 &&
+               error "truncate $scrambledfile should have failed without key"
+
+       rm -f $tmpfile $tmpfile2
+}
+run_test 48a "encrypted file access semantics: truncate"
+
+cleanup_for_enc_tests_othercli() {
+       local othercli=$1
+
+       # remount othercli normally
+       zconf_umount $othercli $MOUNT ||
+               error "umount $othercli $MOUNT failed"
+       zconf_mount $othercli $MOUNT ||
+               error "remount $othercli $MOUNT failed"
+}
+
+test_48b() {
+       local othercli
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       [ "$num_clients" -ge 2 ] || skip "Need at least 2 clients"
+
+       if [ "$HOSTNAME" == ${clients_arr[0]} ]; then
+               othercli=${clients_arr[1]}
+       else
+               othercli=${clients_arr[0]}
+       fi
+
+       stack_trap cleanup_for_enc_tests EXIT
+       stack_trap "cleanup_for_enc_tests_othercli $othercli" EXIT
+       setup_for_enc_tests
+       zconf_umount $othercli $MOUNT ||
+               error "umount $othercli $MOUNT failed"
+
+       cp /bin/sleep $DIR/$tdir/
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       $DIR/$tdir/sleep 30 &
+       # mount and IOs must be done in the same shell session, otherwise
+       # encryption key in session keyring is missing
+       do_node $othercli "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
+                          $MGSNID:/$FSNAME $MOUNT && \
+                          $TRUNCATE $DIR/$tdir/sleep 7"
+       wait || error "wait error"
+       cmp --silent /bin/sleep $DIR/$tdir/sleep ||
+               error "/bin/sleep and $DIR/$tdir/sleep differ"
+}
+run_test 48b "encrypted file: concurrent truncate"
+
+trace_cmd() {
+       local cmd="$@"
+       local xattr_name="security.c"
+
+       cancel_lru_locks
+       $LCTL set_param debug=+info
+       $LCTL clear
+
+       echo $cmd
+       eval $cmd
+       [ $? -eq 0 ] || error "$cmd failed"
+
+       $LCTL dk | grep -E "get xattr '${xattr_name}'|get xattrs"
+       [ $? -ne 0 ] || error "get xattr event was triggered"
+}
+
+test_49() {
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       local dirname=$DIR/$tdir/subdir
+
+       mkdir $dirname
+
+       trace_cmd stat $dirname
+       trace_cmd touch $dirname/f1
+       trace_cmd stat $dirname/f1
+       trace_cmd cat $dirname/f1
+       dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
+       trace_cmd $TRUNCATE $dirname/f1 10240
+       trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
+       trace_cmd $LFS migrate -E -1 -S 256K $dirname/f2
+
+       if [[ $MDSCOUNT -gt 1 ]]; then
+               trace_cmd $LFS setdirstripe -i 1 $dirname/d2
+               trace_cmd $LFS migrate -m 0 $dirname/d2
+               touch $dirname/d2/subf
+               # migrate a non-empty encrypted dir
+               trace_cmd $LFS migrate -m 1 $dirname/d2
+
+               $LFS setdirstripe -i 1 -c 1 $dirname/d3
+               dirname=$dirname/d3/subdir
+               mkdir $dirname
+
+               trace_cmd stat $dirname
+               trace_cmd touch $dirname/f1
+               trace_cmd stat $dirname/f1
+               trace_cmd cat $dirname/f1
+               dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
+               trace_cmd $TRUNCATE $dirname/f1 10240
+               trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
+               trace_cmd $LFS migrate -E -1 -S 256K $dirname/f2
+       else
+               skip_noexit "2nd part needs >= 2 MDTs"
+       fi
+}
+run_test 49 "Avoid getxattr for encryption context"
+
+test_50() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/abc
+       local pagesz=$(getconf PAGESIZE)
+       local sz
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       # write small file, data on MDT only
+       tr '\0' '1' < /dev/zero |
+           dd of=$tmpfile bs=1 count=5000 conv=fsync
+       $LFS setstripe -E 1M -L mdt -E EOF $testfile
+       cp $tmpfile $testfile
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server"
+
+       # decrease size: truncate to PAGE_SIZE
+       $TRUNCATE $tmpfile $pagesz
+       $TRUNCATE $testfile $pagesz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (1)"
+
+       # increase size: truncate to 2 x PAGE_SIZE
+       sz=$((pagesz*2))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (2)"
+
+       # truncate to PAGE_SIZE / 2
+       sz=$((pagesz/2))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (3)"
+
+       # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16
+       sz=$((sz-7))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (4)"
+
+       # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16
+       sz=$((sz+18))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (5)"
+
+       # truncate to a larger, non-multiple of PAGE_SIZE, in a different page
+       sz=$((sz+pagesz+30))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (6)"
+
+       rm -f $testfile
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # write hole in file, data spread on MDT and OST
+       tr '\0' '2' < /dev/zero |
+           dd of=$tmpfile bs=1 count=1539 seek=1539074 conv=fsync,notrunc
+       $LFS setstripe -E 1M -L mdt -E EOF $testfile
+       cp --sparse=always $tmpfile $testfile
+
+       # check that in-memory representation of file is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted in memory"
+
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+
+       # check that file read from server is correct
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted on server"
+
+       # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16,
+       # inside OST part of data
+       sz=$((1024*1024+13))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (7)"
+
+       # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16,
+       # inside MDT part of data
+       sz=7
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (8)"
+
+       # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16,
+       # inside MDT part of data
+       sz=$((1024*1024-13))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (9)"
+
+       # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16,
+       # inside OST part of data
+       sz=$((1024*1024+7))
+       $TRUNCATE $tmpfile $sz
+       $TRUNCATE $testfile $sz
+       cancel_lru_locks osc ; cancel_lru_locks mdc
+       cmp -bl $tmpfile $testfile ||
+               error "file $testfile is corrupted (10)"
+
+       rm -f $tmpfile
+}
+run_test 50 "DoM encrypted file"
+
+test_51() {
+       [ "$MDS1_VERSION" -gt $(version_code 2.13.53) ] ||
+               skip "Need MDS version at least 2.13.53"
+
+       mkdir $DIR/$tdir || error "mkdir $tdir"
+
+       touch $DIR/$tdir/$tfile || error "touch $tfile"
+       cp $(which chown) $DIR/$tdir || error "cp chown"
+       $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile &&
+               error "chown $tfile should fail"
+       setcap 'CAP_CHOWN=ep' $DIR/$tdir/chown || error "setcap CAP_CHOWN"
+       $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile ||
+               error "chown $tfile"
+       rm $DIR/$tdir/$tfile || error "rm $tfile"
+
+       touch $DIR/$tdir/$tfile || error "touch $tfile"
+       cp $(which touch) $DIR/$tdir || error "cp touch"
+       $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile &&
+               error "touch should fail"
+       setcap 'CAP_FOWNER=ep' $DIR/$tdir/touch || error "setcap CAP_FOWNER"
+       $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile ||
+               error "touch $tfile"
+       rm $DIR/$tdir/$tfile || error "rm $tfile"
+
+       local cap
+       for cap in "CAP_DAC_OVERRIDE" "CAP_DAC_READ_SEARCH"; do
+               touch $DIR/$tdir/$tfile || error "touch $tfile"
+               chmod 600 $DIR/$tdir/$tfile || error "chmod $tfile"
+               cp $(which cat) $DIR/$tdir || error "cp cat"
+               $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile &&
+                       error "cat should fail"
+               setcap $cap=ep $DIR/$tdir/cat || error "setcap $cap"
+               $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile ||
+                       error "cat $tfile"
+               rm $DIR/$tdir/$tfile || error "rm $tfile"
+       done
+}
+run_test 51 "FS capabilities ==============="
+
+test_52() {
+       local testfile=$DIR/$tdir/$tfile
+       local tmpfile=$TMP/$tfile
+       local mirror1=$TMP/$tfile.mirror1
+       local mirror2=$TMP/$tfile.mirror2
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       dd if=/dev/urandom of=$tmpfile bs=5000 count=1 conv=fsync
+
+       $LFS mirror create -N -i0 -N -i1 $testfile ||
+               error "could not create mirror"
+
+       dd if=$tmpfile of=$testfile bs=5000 count=1 conv=fsync ||
+               error "could not write to $testfile"
+
+       $LFS mirror resync $testfile ||
+               error "could not resync mirror"
+
+       $LFS mirror verify -v $testfile ||
+               error "verify mirror failed"
+
+       $LFS mirror read -N 1 -o $mirror1 $testfile ||
+               error "could not read from mirror 1"
+
+       cmp -bl $tmpfile $mirror1 ||
+               error "mirror 1 is corrupted"
+
+       $LFS mirror read -N 2 -o $mirror2 $testfile ||
+               error "could not read from mirror 2"
+
+       cmp -bl $tmpfile $mirror2 ||
+               error "mirror 2 is corrupted"
+
+       tr '\0' '2' < /dev/zero |
+           dd of=$tmpfile bs=1 count=9000 conv=fsync
+
+       $LFS mirror write -N 1 -i $tmpfile $testfile ||
+               error "could not write to mirror 1"
+
+       $LFS mirror verify -v $testfile &&
+               error "mirrors should be different"
+
+       rm -f $tmpfile $mirror1 $mirror2
+}
+run_test 52 "Mirrored encrypted file"
+
+test_53() {
+       local testfile=$DIR/$tdir/$tfile
+       local testfile2=$DIR2/$tdir/$tfile
+       local tmpfile=$TMP/$tfile.tmp
+       local resfile=$TMP/$tfile.res
+       local pagesz
+       local filemd5
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       pagesz=$(getconf PAGESIZE)
+       [[ $pagesz == 65536 ]] || skip "Need 64K PAGE_SIZE client"
+
+       do_node $mds1_HOST \
+               "mount.lustre --help |& grep -q 'test_dummy_encryption:'" ||
+                       skip "need dummy encryption support on MDS client mount"
+
+       # this test is probably useless now, but may turn out to be useful when
+       # Lustre supports servers with PAGE_SIZE != 4KB
+       pagesz=$(do_node $mds1_HOST getconf PAGESIZE)
+       [[ $pagesz == 4096 ]] || skip "Need 4K PAGE_SIZE MDS client"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       stack_trap "zconf_umount $mds1_HOST $MOUNT2" EXIT
+       setup_for_enc_tests
+
+       $LFS setstripe -c1 -i0 $testfile
+
+       # write from 1st client
+       cat /dev/urandom | tr -dc 'a-zA-Z0-9' |
+               dd of=$tmpfile bs=$((pagesz+3)) count=2 conv=fsync
+       dd if=$tmpfile of=$testfile bs=$((pagesz+3)) count=2 conv=fsync ||
+               error "could not write to $testfile (1)"
+
+       # read from 2nd client
+       # mount and IOs must be done in the same shell session, otherwise
+       # encryption key in session keyring is missing
+       do_node $mds1_HOST "mkdir -p $MOUNT2"
+       do_node $mds1_HOST \
+               "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
+                $MGSNID:/$FSNAME $MOUNT2 && \
+                dd if=$testfile2 of=$resfile bs=$((pagesz+3)) count=2" ||
+               error "could not read from $testfile2 (1)"
+
+       # compare
+       filemd5=$(do_node $mds1_HOST md5sum $resfile | awk '{print $1}')
+       [ $filemd5 = $(md5sum $tmpfile | awk '{print $1}') ] ||
+               error "file is corrupted (1)"
+       do_node $mds1_HOST rm -f $resfile
+       cancel_lru_locks
+
+       # truncate from 2nd client
+       $TRUNCATE $tmpfile $((pagesz+3))
+       zconf_umount $mds1_HOST $MOUNT2 ||
+               error "umount $mds1_HOST $MOUNT2 failed (1)"
+       do_node $mds1_HOST "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
+                          $MGSNID:/$FSNAME $MOUNT2 && \
+                          $TRUNCATE $testfile2 $((pagesz+3))" ||
+               error "could not truncate $testfile2 (1)"
+
+       # compare
+       cmp -bl $tmpfile $testfile ||
+               error "file is corrupted (2)"
+       rm -f $tmpfile $testfile
+       cancel_lru_locks
+       zconf_umount $mds1_HOST $MOUNT2 ||
+               error "umount $mds1_HOST $MOUNT2 failed (2)"
+
+       # do conversly
+       do_node $mds1_HOST \
+             dd if=/dev/urandom of=$tmpfile bs=$((pagesz+3)) count=2 conv=fsync
+       # write from 2nd client
+       do_node $mds1_HOST \
+          "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
+           $MGSNID:/$FSNAME $MOUNT2 && \
+           dd if=$tmpfile of=$testfile2 bs=$((pagesz+3)) count=2 conv=fsync" ||
+               error "could not write to $testfile2 (2)"
+
+       # read from 1st client
+       dd if=$testfile of=$resfile bs=$((pagesz+3)) count=2 ||
+               error "could not read from $testfile (2)"
+
+       # compare
+       filemd5=$(do_node $mds1_HOST md5sum -b $tmpfile | awk '{print $1}')
+       [ $filemd5 = $(md5sum -b $resfile | awk '{print $1}') ] ||
+               error "file is corrupted (3)"
+       rm -f $resfile
+       cancel_lru_locks
+
+       # truncate from 1st client
+       do_node $mds1_HOST "$TRUNCATE $tmpfile $((pagesz+3))"
+       $TRUNCATE $testfile $((pagesz+3)) ||
+               error "could not truncate $testfile (2)"
+
+       # compare
+       zconf_umount $mds1_HOST $MOUNT2 ||
+               error "umount $mds1_HOST $MOUNT2 failed (3)"
+       do_node $mds1_HOST "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
+                          $MGSNID:/$FSNAME $MOUNT2 && \
+                          cmp -bl $tmpfile $testfile2" ||
+               error "file is corrupted (4)"
+
+       do_node $mds1_HOST rm -f $tmpfile
+       rm -f $tmpfile
+}
+run_test 53 "Mixed PAGE_SIZE clients"
+
+test_54() {
+       local testdir=$DIR/$tdir/$ID0
+       local testfile=$testdir/$tfile
+       local testfile2=$testdir/${tfile}2
+       local tmpfile=$TMP/${tfile}.tmp
+       local resfile=$TMP/${tfile}.res
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       which fscrypt || skip "This test needs fscrypt userspace tool"
+
+       fscrypt setup --force --verbose || error "fscrypt global setup failed"
+       sed -i 's/\(.*\)policy_version\(.*\):\(.*\)\"[0-9]*\"\(.*\)/\1policy_version\2:\3"2"\4/' \
+               /etc/fscrypt.conf
+       fscrypt setup --verbose $MOUNT || error "fscrypt setup $MOUNT failed"
+       mkdir -p $testdir
+       chown -R $ID0:$ID0 $testdir
+
+       echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
+               --source=custom_passphrase --name=protector $testdir" ||
+               error "fscrypt encrypt failed"
+
+       echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
+               --source=custom_passphrase --name=protector2 $testdir" &&
+               error "second fscrypt encrypt should have failed"
+
+       mkdir -p ${testdir}2 || error "mkdir ${testdir}2 failed"
+       touch ${testdir}2/f || error "mkdir ${testdir}2/f failed"
+       cancel_lru_locks
+
+       echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
+               --source=custom_passphrase --name=protector3 ${testdir}2 &&
+               error "fscrypt encrypt on non-empty dir should have failed"
+
+       $RUNAS dd if=/dev/urandom of=$testfile bs=127 count=1 conv=fsync ||
+               error "write to encrypted file $testfile failed"
+       cp $testfile $tmpfile
+       $RUNAS dd if=/dev/urandom of=$testfile2 bs=127 count=1 conv=fsync ||
+               error "write to encrypted file $testfile2 failed"
+       $RUNAS mkdir $testdir/subdir || error "mkdir subdir failed"
+       $RUNAS touch $testdir/subdir/subfile || error "mkdir subdir failed"
+
+       $RUNAS fscrypt lock --verbose $testdir ||
+               error "fscrypt lock $testdir failed (1)"
+
+       $RUNAS ls -R $testdir || error "ls -R $testdir failed"
+       local filecount=$($RUNAS find $testdir -type f | wc -l)
+       [ $filecount -eq 3 ] || error "found $filecount files"
+
+       $RUNAS hexdump -C $testfile &&
+               error "reading $testfile should have failed without key"
+
+       $RUNAS touch ${testfile}.nokey &&
+               error "touch ${testfile}.nokey should have failed without key"
+
+       echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
+               error "fscrypt unlock $testdir failed (1)"
+
+       $RUNAS cat $testfile > $resfile ||
+               error "reading $testfile failed"
+
+       cmp -bl $tmpfile $resfile || error "file read differs from file written"
+
+       $RUNAS fscrypt lock --verbose $testdir ||
+               error "fscrypt lock $testdir failed (2)"
+
+       $RUNAS hexdump -C $testfile2 &&
+               error "reading $testfile2 should have failed without key"
+
+       echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
+               error "fscrypt unlock $testdir failed (2)"
+
+       rm -rf $testdir/*
+       $RUNAS fscrypt lock --verbose $testdir ||
+               error "fscrypt lock $testdir failed (3)"
+
+       rm -f $tmpfile $resfile
+}
+run_test 54 "Encryption policies with fscrypt"
+
+cleanup_55() {
+       # unmount client
+       if is_mounted $MOUNT; then
+               umount_client $MOUNT || error "umount $MOUNT failed"
+       fi
+
+       do_facet mgs $LCTL nodemap_del c0
+       do_facet mgs $LCTL nodemap_modify --name default \
+                --property admin --value 0
+       do_facet mgs $LCTL nodemap_modify --name default \
+                --property trusted --value 0
+       wait_nm_sync default admin_nodemap
+       wait_nm_sync default trusted_nodemap
+
+       do_facet mgs $LCTL nodemap_activate 0
+       wait_nm_sync active 0
+
+       if $SHARED_KEY; then
+               export SK_UNIQUE_NM=false
+       fi
+
+       # remount client
+       mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed"
+       if [ "$MOUNT_2" ]; then
+               mount_client $MOUNT2 ${MOUNT_OPTS} || error "remount failed"
+       fi
+}
+
+test_55() {
+       (( $MDS1_VERSION > $(version_code 2.12.6.2) )) ||
+               skip "Need MDS version at least 2.12.6.3"
+
+       local client_ip
+       local client_nid
+
+       mkdir -p $DIR/$tdir/$USER0/testdir_groups
+       chown root:$ID0 $DIR/$tdir/$USER0
+       chmod 770 $DIR/$tdir/$USER0
+       chmod g+s $DIR/$tdir/$USER0
+       chown $ID0:$ID0 $DIR/$tdir/$USER0/testdir_groups
+       chmod 770 $DIR/$tdir/$USER0/testdir_groups
+       chmod g+s $DIR/$tdir/$USER0/testdir_groups
+
+       # unmount client completely
+       umount_client $MOUNT || error "umount $MOUNT failed"
+       if is_mounted $MOUNT2; then
+               umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+       fi
+
+       do_nodes $(comma_list $(all_mdts_nodes)) \
+               $LCTL set_param mdt.*.identity_upcall=NONE
+
+       stack_trap cleanup_55 EXIT
+
+       do_facet mgs $LCTL nodemap_activate 1
+       wait_nm_sync active
+
+       do_facet mgs $LCTL nodemap_del c0 || true
+       wait_nm_sync c0 id ''
+
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property admin --value 1
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property trusted --value 1
+       wait_nm_sync default admin_nodemap
+       wait_nm_sync default trusted_nodemap
+
+       client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
+       client_nid=$(h2nettype $client_ip)
+       do_facet mgs $LCTL nodemap_add c0
+       do_facet mgs $LCTL nodemap_add_range \
+                --name c0 --range $client_nid
+       do_facet mgs $LCTL nodemap_modify --name c0 \
+                --property admin --value 0
+       do_facet mgs $LCTL nodemap_modify --name c0 \
+                --property trusted --value 1
+       wait_nm_sync c0 admin_nodemap
+       wait_nm_sync c0 trusted_nodemap
+
+       if $SHARED_KEY; then
+               export SK_UNIQUE_NM=true
+               # set some generic fileset to trigger SSK code
+               export FILESET=/
+       fi
+
+       # remount client to take nodemap into account
+       zconf_mount_clients $HOSTNAME $MOUNT $MOUNT_OPTS ||
+               error "remount failed"
+       unset FILESET
+
+       euid_access $USER0 $DIR/$tdir/$USER0/testdir_groups/file
+}
+run_test 55 "access with seteuid"
+
+test_56() {
+       local testfile=$DIR/$tdir/$tfile
+
+       [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       $LFS setstripe -c1 $testfile
+       dd if=/dev/urandom of=$testfile bs=1M count=3 conv=fsync
+       filefrag -v $testfile || error "filefrag $testfile failed"
+       (( $(filefrag -v $testfile | grep -c encrypted) >= 1 )) ||
+               error "filefrag $testfile does not show encrypted flag"
+       (( $(filefrag -v $testfile | grep -c encoded) >= 1 )) ||
+               error "filefrag $testfile does not show encoded flag"
+}
+run_test 56 "FIEMAP on encrypted file"
+
+test_57() {
+       local testdir=$DIR/$tdir/mytestdir
+       local testfile=$DIR/$tdir/$tfile
+
+       [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
+
+       $LCTL get_param mdc.*.import | grep -q client_encryption ||
+               skip "client encryption not supported"
+
+       mount.lustre --help |& grep -q "test_dummy_encryption:" ||
+               skip "need dummy encryption support"
+
+       mkdir $DIR/$tdir
+       mkdir $testdir
+       setfattr -n security.c -v myval $testdir &&
+               error "setting xattr on $testdir should have failed (1)"
+       touch $testfile
+       setfattr -n security.c -v myval $testfile &&
+               error "setting xattr on $testfile should have failed (1)"
+
+       rm -rf $DIR/$tdir
+
+       stack_trap cleanup_for_enc_tests EXIT
+       setup_for_enc_tests
+
+       mkdir $testdir
+       setfattr -n security.c -v myval $testdir &&
+               error "setting xattr on $testdir should have failed (2)"
+       touch $testfile
+       setfattr -n security.c -v myval $testfile &&
+               error "setting xattr on $testfile should have failed (2)"
+       return 0
+}
+run_test 57 "security.c xattr protection"
+
 log "cleanup: ======================================================"
 
 sec_unsetup() {
 log "cleanup: ======================================================"
 
 sec_unsetup() {