#!/bin/sh
# - fs
# - mkfs
# - mount
# - mount_option
# - nr_tmpfs
# mount_to
# mount_bind

# normal disks will mount to $mount_points/{nfs, fs}/
# mount_to is for mount disks to specified directory.
#	use it by:
#	  disk:
#         - 1HDD
#         fs:
#         - xfs
#         mount_to: /mnt/sda
#      or
#         disk:
#         - 2HDD
#         fs:
#         - xfs
#         mount_to:
#         - /mnt/sda
#         - /mnt/sdb
# mount_bind will mount only the first mount point of mount_to array, and mount all the rest mount points of mount_to array bind to the first mount point,
# if $mount_bind=true, will call function mount_bind() in this script,
# if $mount_bind is not true or not exist, will not call function mount_bind(), just mount the every disk to every mount point.
# This script supports 2 NFS mount schemes:
# fs1: followup scripts will see NFS mount_points only
# fs2: followup scripts will see NFS mount_points as well as original mount_points

[ -n "$fs" ] || exit 0

. $LKP_SRC/lib/reproduce-log.sh
. $LKP_SRC/lib/fs_ext.sh

[ -n "$mount_option" ] && mount_option="-o $mount_option"

def_mount=
def_mkfs=
fs_options() {
	case $fs in
	xfs)
		def_mount="-o inode64"
		[ "${raid_level#*raid}" != "$raid_level" ] && [ "$nr_partitions" -gt 1 ] && {
			def_mount="${def_mount},logbsize=262144"
			def_mkfs="-f -d agcount=$nr_partitions"
		}
		ensure_mkfs='-f'
		;;
	ext*)
		ensure_mkfs='-q -F'
		;;
	btrfs)
		;;
	f2fs)
		modprobe f2fs 2>/dev/null
		;;
	nfsv3)
		def_mount="-o vers=3"
		fs="nfs"
		;;
	nfsv4)
		def_mount="-o vers=4"
		fs="nfs"
		;;
	udf)
		;;
	ocfs2)
		ensure_mkfs='-q -F'
		;;
	esac
}

is_btrfs_raid_levels() {
	[ "$fs" = 'btrfs' ] && [ "$raid_level" = 'braid0' -o \
				 "$raid_level" = 'braid1' -o \
				 "$raid_level" = 'braid5' -o \
				 "$raid_level" = 'braid6' -o \
				 "$raid_level" = 'braid10' ]
}

make_fs() {
	is_btrfs_raid_levels && {
		log_cmd mkfs.btrfs --data ${raid_level#b} -m ${raid_level#b} $mkfs $ensure_mkfs $partitions || exit
		return
	}

	[ "$fs" = 'ocfs2' ] && {
		start_o2cb || exit
	}

	local pids=
	for dev in $bdevs
	do
		log_cmd mkfs -t $fs ${mkfs:-$def_mkfs} $ensure_mkfs $dev &
		pids="${pids} $! "
	done

	local pid
	for pid in $pids; do
		wait $pid || exit
	done
}

probe_filesystem()
{
	local fs=$1
	grep -w $fs /proc/filesystems || log_cmd modprobe $fs
}

mount_fs() {
	local bdevs_num=0
	for dev in $bdevs
	do
		local mnt
		bdevs_num=$(($bdevs_num + 1))

		[ -n "$mount_to" ] && mnt=$(echo $mount_to | awk "{print \$${bdevs_num}}")
		mnt=${mnt:-/fs/$(basename $dev)}
		log_cmd mkdir -p $mnt
		probe_filesystem $fs
		log_cmd mount -t $fs ${mount:-$def_mount} $mount_option $dev $mnt || exit
		mount_points="${mount_points}$mnt "
	done

	[ "$mount_bind" == "true" ] && mount_bind
}

mount_bind()
{
	mount_array=($mount_to)
	num=$(echo ${#mount_array[@]})
	[ "$num" -gt "1" ] && {
		for i in ${!mount_array[@]}
		do
			[ "$i" == "0" ] && continue
			log_cmd mkdir -p ${mount_array[$i]}
			mount --bind ${mount_array[0]} ${mount_array[$i]}
		done
	}
}

if is_btrfs_raid_levels; then
	bdevs="${partitions%% *}"
else
	bdevs="$partitions"
fi

fs_options

case $fs in
	nfs)
		start_nfsd $mount_points
		mount_local_nfs $mount_points
		[ "${0#*fs1}" != "$0" ] && mount_points=
		;;

	tmpfs)
		: ${nr_tmpfs:=1}
		mount_tmpfs $nr_tmpfs
		;;

	*)
		. $LKP_SRC/lib/fs_ext.sh
		if [ -n "$raid_device" ] || [ -n "$LKP_LOCAL_RUN" ]; then
			destroy_fs
		else
			destroy_devices
		fi
		make_fs
		mount_fs
		;;
esac

cat > "$TMP_RESULT_ROOT/post-run.fs" <<EOF

#!/bin/sh

umount_fs() {
	for mt in $nfs_mount_points $mount_points; do
		mountpoint -q \$mt && umount \$mt
	done
}

umount_fs
EOF

cat >> $TMP/env.yaml <<EOF

# setup/fs
fs: $fs
mount_points: $nfs_mount_points $mount_points
EOF
