the second open(2) call to file in samba 2.0 cifs mountpoint hang

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Process A open(2) file1 in samba 2.0 cifs mountpoint then sleep.
Process B try to open(2) the same file1. B is blocked in open
until A stops sleep and exit.

O_NONBLOCK is not working either.

This does not happen on samba 3.0.

Reproduced on 4.16-rc5 Linus tree.

Thanks,
Xiong

Reproducer:

--------------------- start test.sh ------------------------------
#! /bin/bash

err_exit() { echo -e $1; exit 1; }

setup_cifs()
{
	local cifs_tst_export=/export/cifstest
	local cifs_sch_export=/export/cifsscratch
	mkdir -p $cifs_tst_export $cifs_sch_export

	\cp -f /etc/samba/smb.conf{,.bak}
	cat > /etc/samba/smb.conf << EOF
[test]
    path = $cifs_tst_export
    writeable = yes
[scratch]
    path = $cifs_sch_export
    writeable = yes
EOF
	which systemctl && systemctl restart smb > /dev/null 2>&1
	service stop smb > /dev/null 2>&1
	restorecon /etc/samba/smb.conf
	testparm -s
	chcon -t samba_share_t $cifs_sch_export
	chcon -t samba_share_t $cifs_tst_export
	echo -e "redhat\nredhat" | smbpasswd -a root
	service start smb > /dev/null 2>&1
}

preset_cifs()
{
	local vers=${1:-3.0}
	echo Testing $vers
	TEST_DEV=//localhost/test
	SCRATCH_DEV=//localhost/scratch
	TEST_DIR=/cifsmnt
	SCRATCH_MNT=/cifssch
	umount $TEST_DEV $SCRATCH_DEV $TEST_DIR $SCRATCH_MNT > /dev/null 2>&1
	mkdir -p $TEST_DIR $SCRATCH_MNT
	MOUNT_OPTIONS="-o vers=${vers},username=root,password=redhat"
	TEST_FS_MOUNT_OPTS="-o vers=${vers},username=root,password=redhat"

	mount.cifs $TEST_DEV $TEST_DIR $MOUNT_OPTIONS || err_exit "cifs mount $TEST_DEV failed"
	mount.cifs $SCRATCH_DEV $SCRATCH_MNT $MOUNT_OPTIONS || err_exit "cifs mount $SCRATCH_DEV failed"
}

cleanup_cifs()
{
	umount $SCRATCH_MNT $TEST_DIR
	\cp -f /etc/samba/smb.conf{.bak,}
	which systemctl && systemctl restart smb
	service stop smb > /dev/null 2>&1
	service start smb > /dev/null 2>&1
}

do_test()
{
	touch $SCRATCH_MNT/testfile
	mount | grep $SCRATCH_MNT
	./open_wait $SCRATCH_MNT/testfile &
	./open $SCRATCH_MNT/testfile
	echo ""
	wait
}

rpm -qv cifs-utils || yum intsall -y cifs-utils
rpm -qv samba || yum intsall -y samba samba-client
setup_cifs
cc open_wait.c -o open_wait
cc open.c -o open
preset_cifs 3.0
do_test
preset_cifs 2.0
do_test
preset_cifs 2.1
do_test
preset_cifs 1.0
do_test
cleanup_cifs
rm -f open_wait open a.out
exit
--------------------- end test.sh ------------------------------
--------------------- start open.c  ------------------------------
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>

static int fd;

static void err_exit(char *op, int errn)
{
	fprintf(stderr, "%s: %s\n", op, strerror(errn));
	if (fd > 0)
		close(fd);
	exit(errn);
}

int main(int argc, char **argv)
{
	struct timeval tv1, tv2;
	long double t1, t2;

	gettimeofday(&tv1, NULL);
	//fd = open(argv[1], O_RDWR|O_NONBLOCK);
	fd = open(argv[1], O_RDWR);
	gettimeofday(&tv2, NULL);

	t1 = (long double)(tv1.tv_sec) + (long double)(tv1.tv_usec/1000000.0);
	t2 = (long double)(tv2.tv_sec) + (long double)(tv2.tv_usec/1000000.0);
	printf("open %s: %llf seconds\n", argv[1], t2 - t1);
	err_exit("open", errno);
}
--------------------- end open.c  ------------------------------
--------------------- start open_wait.c  ------------------------------
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

static int fd;

static void err_exit(char *op, int errn)
{
	fprintf(stderr, "%s: %s\n", op, strerror(errn));
	if (fd > 0)
		close(fd);
	exit(errn);
}

int main(int argc, char **argv)
{
	fd = open(argv[1], O_RDWR);
	if (fd == -1)
		err_exit("open", errno);

	sleep(2);
	close(fd);
	return 0;
}
--------------------- end open_wait.c  ------------------------------
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux