diff --git a/build/rpm/xfstests.spec.in b/build/rpm/xfstests.spec.in
index e0f7c5f9..3dce41ef 100644
--- a/build/rpm/xfstests.spec.in
+++ b/build/rpm/xfstests.spec.in
@@ -17,7 +17,7 @@ Group: System Environment/Base
 
 %description
 The XFS regression test suite.  Also includes some support for
-acl, attr, udf, and nfs testing.  Contains around 200 specific tests
+acl, attr, udf, nfs and afs testing.  Contains around 200 specific tests
 for userspace & kernelspace.
 
 %prep
diff --git a/check b/check
index 1a58a2b2..d4bb4126 100755
--- a/check
+++ b/check
@@ -57,6 +57,7 @@ usage()
 
 check options
     -nfs		test NFS
+    -afs		test AFS
     -glusterfs		test GlusterFS
     -cifs		test CIFS
     -9p			test 9p
@@ -280,7 +281,7 @@ while [ $# -gt 0 ]; do
 	case "$1" in
 	-\? | -h | --help) usage ;;
 
-	-nfs|-glusterfs|-cifs|-9p|-fuse|-virtiofs|-pvfs2|-tmpfs|-ubifs)
+	-nfs|-afs|-glusterfs|-cifs|-9p|-fuse|-virtiofs|-pvfs2|-tmpfs|-ubifs)
 		FSTYP="${1:1}"
 		;;
 	-overlay)
diff --git a/common/config b/common/config
index 6c8cb3a5..25fbec14 100644
--- a/common/config
+++ b/common/config
@@ -301,6 +301,7 @@ export BTRFS_TUNE_PROG=$(type -P btrfstune)
 export BTRFS_CORRUPT_BLOCK_PROG=$(type -P btrfs-corrupt-block)
 export XFS_FSR_PROG=$(type -P xfs_fsr)
 export MKFS_NFS_PROG="false"
+export MKFS_AFS_PROG="false"
 export MKFS_CIFS_PROG="false"
 export MKFS_OVERLAY_PROG="false"
 export MKFS_REISER4_PROG=$(type -P mkfs.reiser4)
@@ -353,6 +354,9 @@ _common_mount_opts()
 	nfs)
 		echo $NFS_MOUNT_OPTIONS
 		;;
+	afs)
+		echo $AFS_MOUNT_OPTIONS
+		;;
 	cifs)
 		echo $CIFS_MOUNT_OPTIONS
 		;;
@@ -420,6 +424,9 @@ _mkfs_opts()
 	nfs)
 		export MKFS_OPTIONS=$NFS_MKFS_OPTIONS
 		;;
+	afs)
+		export MKFS_OPTIONS=$AFS_MKFS_OPTIONS
+		;;
 	cifs)
 		export MKFS_OPTIONS=$CIFS_MKFS_OPTIONS
 		;;
@@ -510,6 +517,8 @@ _source_specific_fs()
 	nfs)
 		. ./common/nfs
 		;;
+	afs)
+		;;
 	cifs)
 		;;
 	9p)
@@ -588,9 +597,9 @@ _check_device()
 	fi
 
 	case "$FSTYP" in
-	9p|fuse|tmpfs|virtiofs)
-		# 9p, fuse and virtiofs mount tags are just plain strings, so anything is allowed
-		# tmpfs doesn't use mount source, ignore
+	9p|fuse|tmpfs|virtiofs|afs)
+		# 9p, fuse, virtiofs and afs mount tags are just plain strings,
+		# so anything is allowed tmpfs doesn't use mount source, ignore
 		;;
 	ceph)
 		# ceph has two different possible syntaxes for mount devices. The
diff --git a/common/rc b/common/rc
index 90749343..8b8cb714 100644
--- a/common/rc
+++ b/common/rc
@@ -569,6 +569,9 @@ _test_mkfs()
     nfs*)
 	# do nothing for nfs
 	;;
+    afs*)
+	# do nothing for afs
+	;;
     cifs)
 	# do nothing for cifs
 	;;
@@ -614,6 +617,9 @@ _try_mkfs_dev()
     nfs*)
 	# do nothing for nfs
 	;;
+    afs*)
+	# do nothing for afs
+	;;
     9p)
 	# do nothing for 9p
 	;;
@@ -660,7 +666,7 @@ _mkfs_dev()
     rm -f $tmp.mkfserr $tmp.mkfsstd
 }
 
-# remove all files in $SCRATCH_MNT, useful when testing on NFS/CIFS
+# remove all files in $SCRATCH_MNT, useful when testing on NFS/AFS/CIFS
 _scratch_cleanup_files()
 {
 	case $FSTYP in
@@ -688,7 +694,7 @@ _scratch_mkfs()
 	local mkfs_status
 
 	case $FSTYP in
-	nfs*|cifs|ceph|overlay|glusterfs|pvfs2|9p|fuse|virtiofs)
+	nfs*|afs|cifs|ceph|overlay|glusterfs|pvfs2|9p|fuse|virtiofs)
 		# unable to re-create this fstyp, just remove all files in
 		# $SCRATCH_MNT to avoid EEXIST caused by the leftover files
 		# created in previous runs
@@ -1571,7 +1577,7 @@ _check_mounted_on()
 
 	if [ -n "$type" -a "`_fs_type $dev`" != "$type" ]; then
 		echo "$devname=$dev is mounted but not a type $type filesystem"
-		# raw $DF_PROG cannot handle NFS/CIFS/overlay correctly
+		# raw $DF_PROG cannot handle NFS/AFS/CIFS/overlay correctly
 		_df_device $dev
 		return 3 # 3 = mounted as wrong type
 	fi
@@ -1610,6 +1616,15 @@ _require_scratch_nocheck()
 			_notrun "this test requires a valid \$SCRATCH_MNT"
 		fi
 		;;
+	afs)
+		echo $SCRATCH_DEV | grep -q "^%" > /dev/null 2>&1
+		if [ -z "$SCRATCH_DEV" -o "$?" != "0" ]; then
+			_notrun "this test requires a valid \$SCRATCH_DEV"
+		fi
+		if [ ! -d "$SCRATCH_MNT" ]; then
+			_notrun "this test requires a valid \$SCRATCH_MNT"
+		fi
+		;;
 	ceph)
 		echo $SCRATCH_DEV | grep -qE "=/|:/" > /dev/null 2>&1
 		if [ -z "$SCRATCH_DEV" -o "$?" != "0" ]; then
@@ -1810,6 +1825,15 @@ _require_test()
 			_notrun "this test requires a valid \$TEST_DIR"
 		fi
 		;;
+	afs)
+		echo $TEST_DEV | grep -q "^%" > /dev/null 2>&1
+		if [ -z "$TEST_DEV" -o "$?" != "0" ]; then
+			_notrun "this test requires a valid \$TEST_DEV"
+		fi
+		if [ ! -d "$TEST_DIR" ]; then
+			_notrun "this test requires a valid \$TEST_DIR"
+		fi
+		;;
 	ceph)
 		echo $TEST_DEV | grep -qE "=/|:/" > /dev/null 2>&1
 		if [ -z "$TEST_DEV" -o "$?" != "0" ]; then
@@ -2923,7 +2947,7 @@ _scratch_mkfs_richacl()
 		;;
 	ext4)   _scratch_mkfs -O richacl
 		;;
-	nfs*|cifs|overlay)
+	nfs*|afs|cifs|overlay)
 		_scratch_mkfs
 		;;
 	esac
@@ -3163,6 +3187,9 @@ _check_test_fs()
     nfs)
 	# no way to check consistency for nfs
 	;;
+    afs)
+	# no way to check consistency for afs
+	;;
     cifs)
 	# no way to check consistency for cifs
 	;;
@@ -3227,6 +3254,9 @@ _check_scratch_fs()
     nfs*)
 	# Don't know how to check an NFS filesystem, yet.
 	;;
+    afs*)
+	# Don't know how to check an AFS filesystem, yet.
+	;;
     cifs)
 	# Don't know how to check a CIFS filesystem, yet.
 	;;
@@ -3996,7 +4026,7 @@ _require_atime()
 {
 	_exclude_scratch_mount_option "noatime"
 	case $FSTYP in
-	nfs|cifs|virtiofs)
+	nfs|afs|cifs|virtiofs)
 		_notrun "atime related mount options have no effect on $FSTYP"
 		;;
 	esac
@@ -4532,7 +4562,7 @@ _require_congruent_file_oplen()
 	local oplen="$2"
 
 	case $FSTYP in
-	nfs*|cifs|9p|virtiofs|ceph|glusterfs|overlay|pvfs2)
+	nfs*|afs|cifs|9p|virtiofs|ceph|glusterfs|overlay|pvfs2)
 		# Network filesystems don't know about (or tell the client
 		# about) the underlying file allocation unit and they generally
 		# pass the file IO request to the underlying filesystem, so we
