Attached is the third part of the patches for file record locking:
libfshelp-tests_rlock.patch
fcntl.diff

The patch fcntl.diff against glibc-2.29-1 should be applied after
(or at the same time as) the patched hurd debs.

Note that the following glibc patch have been commented out from the
series file:
hurd-i386/tg-WRLCK-upgrade.diff

Additionally the two upstream commits are reversed by:
revert-git-lockf-0.diff
revert-git-fcntl64.diff

If you are working with git these commits are more easily mage there.

Thanks!
sysdeps/mach/hurd/Changelog
2019-01-12  Svante Signell <svante.sign...@gmail.com>

	* Update copyright years.

2018-12-21  Svante Signell <svante.sign...@gmail.com>

	* hurd-i386/fcntl.diff: Add the required new arguments when
	  calling the updated RPC file_record_lock.

2018-12-04  Svante Signell <svante.sign...@gmail.com>

	* debian/patches/series: Comment out debian 2.28-1 patches:
	  hurd-i386/git-fcntl64.diff
	  hurd-i386/git-lockf-0.diff
	  hurd-i386/tg-WRLCK-upgrade.diff

	* fcntl.c: Add support weak, hidden and strong references as
	  in Debian 2.28-1 patch as in hurd-i386/git-fcntl64.diff.

	* fcntl64.c: New file, defined in fcntl.c as an alias. 

	* hurd-i386/fcntl.diff: Refresh.

2014-08-21  Svante Signell <svante.sign...@gmail.com>

	* fcntl.c: Add support for file-record-lock RPC fixing posix
          file locking using the flock64 version of struct flock.

	* bits/fcntl.h: Since MIG cannot mix 32 bit and 64 bit
          integers define unique numbers for F_GETLK64, F_SETLK64 and
          F_SETLKW64 to prepare for a flock64 implementation of file
          record locking in hurd.

Index: glibc-2.28-4.1/sysdeps/mach/hurd/bits/fcntl.h
===================================================================
--- glibc-2.28-4.1.orig/sysdeps/mach/hurd/bits/fcntl.h
+++ glibc-2.28-4.1/sysdeps/mach/hurd/bits/fcntl.h
@@ -1,5 +1,5 @@
 /* O_*, F_*, FD_* bit values for GNU.
-   Copyright (C) 1993-2018 Free Software Foundation, Inc.
+   Copyright (C) 1993-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -163,9 +163,18 @@
 # define F_GETOWN	5	/* Get owner (receiver of SIGIO).  */
 # define F_SETOWN	6	/* Set owner (receiver of SIGIO).  */
 #endif
+#ifdef __USE_FILE_OFFSET64
+# define	F_GETLK		F_GETLK64
+# define	F_SETLK		F_SETLK64
+# define	F_SETLKW	F_SETLKW64
+#else
 #define	F_GETLK		7	/* Get record locking info.  */
 #define	F_SETLK		8	/* Set record locking info (non-blocking).  */
 #define	F_SETLKW	9	/* Set record locking info (blocking).  */
+#endif
+#define	F_GETLK64	10	/* Get record locking info.  */
+#define	F_SETLK64	11	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW64	12	/* Set record locking info (blocking).  */
 
 #ifdef __USE_XOPEN2K8
 # define F_DUPFD_CLOEXEC 1030	/* Duplicate, set FD_CLOEXEC on new one.  */
Index: glibc-2.28-4.1/sysdeps/mach/hurd/fcntl.c
===================================================================
--- glibc-2.28-4.1.orig/sysdeps/mach/hurd/fcntl.c
+++ glibc-2.28-4.1/sysdeps/mach/hurd/fcntl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +20,6 @@
 #include <hurd.h>
 #include <hurd/fd.h>
 #include <stdarg.h>
-#include <sys/file.h>		/* XXX for LOCK_* */
 
 /* Perform file control operations on FD.  */
 int
@@ -128,31 +127,27 @@ __libc_fcntl (int fd, int cmd, ...)
     case F_SETLK:
     case F_SETLKW:
       {
-	/* XXX
-	   We need new RPCs to support POSIX.1 fcntl file locking!!
-	   For the time being we support the whole-file case only,
-	   with all kinds of WRONG WRONG WRONG semantics,
-	   by using flock.  This is definitely the Wrong Thing,
-	   but it might be better than nothing (?).  */
 	struct flock *fl = va_arg (ap, struct flock *);
-	va_end (ap);
+	mach_port_t rendezvous = MACH_PORT_NULL;
+
 	switch (cmd)
 	  {
 	  case F_GETLK:
-	    errno = ENOSYS;
-	    return -1;
+	    cmd = F_GETLK64;
+	    break;
 	  case F_SETLK:
-	    cmd = LOCK_NB;
+	    cmd = F_SETLK64;
 	    break;
-	  default:
-	    cmd = 0;
+	  case F_SETLKW:
+	    cmd = F_SETLKW64;
 	    break;
 	  }
 	switch (fl->l_type)
 	  {
-	  case F_RDLCK: cmd |= LOCK_SH; break;
-	  case F_WRLCK: cmd |= LOCK_EX; break;
-	  case F_UNLCK: cmd |= LOCK_UN; break;
+	  case F_RDLCK:
+	  case F_WRLCK:
+	  case F_UNLCK:
+	    break;
 	  default:
 	    errno = EINVAL;
 	    return -1;
@@ -160,24 +155,73 @@ __libc_fcntl (int fd, int cmd, ...)
 	switch (fl->l_whence)
 	  {
 	  case SEEK_SET:
-	    if (fl->l_start == 0 && fl->l_len == 0) /* Whole file request.  */
-	      break;
-	    /* It seems to be common for applications to lock the first
-	       byte of the file when they are really doing whole-file locking.
-	       So, since it's so wrong already, might as well do that too.  */
-	    if (fl->l_start == 0 && fl->l_len == 1)
-	      break;
-	    /* FALLTHROUGH */
 	  case SEEK_CUR:
 	  case SEEK_END:
-	    errno = ENOTSUP;
+	    break;
+	  default:
+	    errno = EINVAL;
 	    return -1;
+	  }
+
+	struct flock64 fl64 = {
+	  .l_type = fl->l_type,
+	  .l_whence = fl->l_whence,
+	  .l_start = fl->l_start,
+	  .l_len = fl->l_len,
+	  .l_pid = fl->l_pid
+	};
+
+	err = HURD_FD_PORT_USE (d, __file_record_lock (port, cmd, &fl64, rendezvous, MACH_MSG_TYPE_MAKE_SEND));
+
+	fl->l_type = fl64.l_type;
+	fl->l_whence = fl64.l_whence;
+	fl->l_start = fl64.l_start;
+	fl->l_len = fl64.l_len;
+	fl->l_pid = fl64.l_pid;
+	if ((sizeof fl->l_start != sizeof fl64.l_start
+	     && fl->l_start != fl64.l_start)
+	  || (sizeof fl->l_len != sizeof fl64.l_len
+	      && fl->l_len != fl64.l_len))
+	  {
+	    __set_errno (EOVERFLOW);
+	    return -1;
+	  }
+
+	result = err ? __hurd_dfail (fd, err) : 0;
+	break;
+      }
+
+    case F_GETLK64:
+    case F_SETLK64:
+    case F_SETLKW64:
+      {
+	struct flock64 *fl64 = va_arg (ap, struct flock64 *);
+	mach_port_t rendezvous = MACH_PORT_NULL;
+
+	switch (fl64->l_type)
+	  {
+	  case F_RDLCK:
+	  case F_WRLCK:
+	  case F_UNLCK:
+	    break;
+	  default:
+	    errno = EINVAL;
+	    return -1;
+	  }
+	switch (fl64->l_whence)
+	  {
+	  case SEEK_SET:
+	  case SEEK_CUR:
+	  case SEEK_END:
+	    break;
 	  default:
 	    errno = EINVAL;
 	    return -1;
 	  }
 
-	return __flock (fd, cmd);
+	err = HURD_FD_PORT_USE (d, __file_record_lock (port, cmd, fl64, rendezvous, MACH_MSG_TYPE_MAKE_SEND));
+	result = err ? __hurd_dfail (fd, err) : 0;
+	break;
       }
 
     case F_GETFL:		/* Get per-open flags.  */
@@ -215,3 +259,4 @@ strong_alias (__libc_fcntl, __libc_fcntl
 libc_hidden_def (__libc_fcntl64)
 weak_alias (__libc_fcntl64, __fcntl64)
 libc_hidden_weak (__fcntl64)
+weak_alias (__fcntl64, fcntl64)
Index: glibc-2.28-4.1/sysdeps/mach/hurd/fcntl64.c
===================================================================
--- /dev/null
+++ glibc-2.28-4.1/sysdeps/mach/hurd/fcntl64.c
@@ -0,0 +1 @@
+/* fcntl64 is defined in fcntl.c as an alias.  */
./ChangeLog

2019-03-04  Svante Signell <svante.sign...@gmail.com>

	* test-*.c: Update code, remove test results.
	* README.new_tests: New file, summarize new test results. 

2019-02-12  Svante Signell <svante.sign...@gmail.com>

	* test-*.c: Update code, add some test results.
	* Makefile: Remove extra flags.

w2019-02-01  Svante Signell <svante.sign...@gmail.com>

	* Update copyright years.

2016-05-23  Svante Signell <svante.sign...@gmail.com>

        * Makefile: Add sub-directory libfshelp-tests.

libfshelp-tests/ChangeLog
2018-12-07  Svante Signell <svante.sign...@gmail.com>

        * Update copyright years.
	* locks.c(cmd_lock): Call fshelp_rlock_tweak()
          with new last argument rendezvous = MACH_PORT_NULL.

2017-01-05  Svante Signell <svante.sign...@gmail.com>

	* Update copyright years and headers.

2016-12-28  Svante Signell <svante.sign...@gmail.com>

	* Makefile: test-flock.c, test-lockf.c and test-fcntl.c
	* test-lockf.c: New file
	* Rename set-flock.c, set-fcntl.c to test-flock.c test-fcntl.c
	* TODO: Update README

2016-05-23  Svante Signell <svante.sign...@gmail.com>

	* Makefile: Link with pthread, add build of set-flock.c and set-fcntl.c
	* define temporary CPP_FLAGS until glibc is updated
	* set-flock.c, set-fcntl.c: New files.
	* Fix typos in README

2001-04-11  Neal H Walfield  <n...@cs.uml.edu>

	* ChangeLog: New file, mentioning itself in this sentence.
	* Makefile: New file.
	* README: Likewise.
	* fork.c: Likewise.
	* locks: Likewise.
	* locks-tests: Likewise.
	* locks.c: Likewise.
	* race.c: Likewise.

Index: hurd-0.9.git20190331-8.2/Makefile
===================================================================
--- hurd-0.9.git20190331-8.2.orig/Makefile
+++ hurd-0.9.git20190331-8.2/Makefile
@@ -1,6 +1,6 @@
 #
-#   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2004,
-#   2006, 2009, 2011, 2012, 2013 Free Software Foundation, Inc.
+#   Copyright (C) 1993-1999, 2001, 2002, 2004, 2006, 2009,
+#   2011-2013, 2015-2019 Free Software Foundation, Inc.
 #
 #   This program is free software; you can redistribute it and/or
 #   modify it under the terms of the GNU General Public License as
@@ -46,7 +46,7 @@ prog-subdirs = auth proc exec term \
 	       storeio pflocal pfinet defpager mach-defpager \
 	       login daemons boot console \
 	       hostmux usermux ftpfs trans \
-	       console-client utils sutils \
+	       console-client utils sutils libfshelp-tests \
 	       benchmarks fstests \
 	       procfs \
 	       startup \
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/Makefile
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/Makefile
@@ -0,0 +1,42 @@
+# Makefile libfshelp test cases
+#
+#   Copyright (C) 2001, 2015-2019 Free Software Foundation, Inc.
+#
+#   Written by Neal H Walfield <n...@cs.uml.edu>
+#
+#   This file is part of the GNU Hurd.
+#
+#   This program is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU General Public License as
+#   published by the Free Software Foundation; either version 2, or (at
+#   your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.
+
+dir := libfshelp-tests
+makemode := utilities
+
+targets = race locks fork test-flock test-lockf test-fcntl
+SRCS = race.c locks.c fork.c test-flock.c test-lockf.c test-fcntl.c
+
+MIGSTUBS = fsUser.o ioUser.o
+OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
+HURDLIBS = fshelp ports
+LDLIBS += -lpthread
+
+race: race.o fsUser.o ioUser.o
+fork: fork.o fsUser.o
+locks: locks.o
+test-flock: test-flock.o
+test-lockf: test-lockf.o
+test-fcntl: test-fcntl.o ../libfshelp/libfshelp.a
+
+race locks: ../libfshelp/libfshelp.a ../libports/libports.a ../libshouldbeinlibc/libshouldbeinlibc.a
+
+include ../Makeconf
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/README
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/README
@@ -0,0 +1,102 @@
+These programs are used to help test the algorithms in the libfshelp
+library.
+
+Record Locking
+==============
+
+Race
+----
+
+Race locks a file, reads an integer, increments it, writes the result to
+the file and then unlocks the file -- 10,000 times.  It is intended that
+multiple instances of this program be run at the same time.  Race takes
+three arguments:  the file to use, the start of the lock and the length.
+For obvious reasons, it is important that all instances of race have
+locks that overlap.  For example:
+
+	# rm -f foo && ( ./race foo 2 0 & ./race foo 2 3 & \
+	> ./race foo 0 3 )
+	Was blocked 5482 times
+	Was blocked 5485 times
+	Was blocked 5479 times
+	# cat foo
+	30000
+
+We see here that each process was blocked several thousand times and that
+the result in the file foo is 30000.  Perfect.
+
+Locks
+-----
+
+Locks is an interactive shell that has one ``file'' and ten open file
+descriptors.  Using some simple commands, one can test to see if locks
+are established, cleared, and enforced.  The principal command is
+`lock,' which takes four parameters.  The first is the file descriptor
+to lock, the second is the start of the lock, the third is the length of
+the lock (0 = until EOF) and the last is the type of lock to establish
+from the set {0: F_UNLCK, 1: F_RDLCK, 2: F_WRLCK}.  Help on the other
+commands can be gotten using the `help' command.
+
+A small run:
+
+	# ./locks
+	> lock 0 10 0 1
+	  0:    Start =   10; Length =    0; Type = F_RDLCK
+
+Lock from byte 10 through the EOF.
+
+	> lock 0 20 0 0
+	  0:    Start =   10; Length =   10; Type = F_RDLCK
+
+Unlock from byte 20 through the EOF.
+
+	> lock 0 11 8 2
+	  0:    Start =   10; Length =    1; Type = F_RDLCK
+	        Start =   11; Length =    8; Type = F_WRLCK
+	        Start =   19; Length =    1; Type = F_RDLCK
+
+Upgrade bytes 11 through 19 to a write lock.
+
+	> lock 0 9 10 1
+	  0:    Start =    9; Length =    2; Type = F_RDLCK
+	        Start =   11; Length =    8; Type = F_WRLCK
+	        Start =   19; Length =    1; Type = F_RDLCK
+
+Add a read lock to byte 9.
+
+	> lock 1 0 10 1
+	  1:    Start =    0; Length =   10; Type = F_RDLCK
+
+Read lock the first ten bytes of the file through file descriptor 1.
+
+	> lock 1 10 0 1
+	Resource temporarily unavailable
+
+Attempts to read lock the rest of the file.  This, however, fails as
+there are outstanding write locks held through file descriptor 1.
+
+	> lock 1 10 0 0
+	  1:    Start =    0; Length =   10; Type = F_RDLCK
+
+What happens when file descriptor tries to unlock the blocked range?
+
+	> lock 1 10 0 2
+	Resource temporarily unavailable
+
+Nothing.
+
+A bunch of tests live in locks-tests.  One can run them through the test
+program using: `./locks < ./locks-test 2>&1 | less'.  If it core dumps or
+triggers an assertion, that is a bug.  Report it.
+
+Fork
+----
+
+Tests to see if the a child inherits the locks across a fork.  According
+to POSIX, the child should not.
+
+	# ./fork foo
+	Parent has a write lock; Others have a write lock.
+	Child has a write lock; Others have a write lock.
+
+We are not POSIX compliant.
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/fork.c
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/fork.c
@@ -0,0 +1,80 @@
+/* Test is a process inherits locks after a fork.
+
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+   Written by Neal H Walfield <n...@cs.uml.edu>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <stdio.h>
+#include <error.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include "fs_U.h"
+#include <hurd.h>
+
+char *lock2str (int type)
+{
+  if (type & LOCK_SH)
+    return "read";
+  if (type & LOCK_EX)
+    return "write";
+  if (type & LOCK_UN)
+    return "unlocked";
+ assert (! "Invalid");
+ return NULL;
+}
+
+int main (int argc, char **argv)
+{
+  error_t err;
+  struct flock64 lock;
+  mach_port_t rendezvous = MACH_PORT_NULL;
+  int fd;
+  pid_t pid;
+  int mine, others;
+
+  if (argc != 2)
+    error (1, 0, "Usage: %s file", argv[0]);
+
+  lock.l_whence = SEEK_SET;
+  lock.l_start = 0;
+  lock.l_len = 0;
+  lock.l_type = F_WRLCK;
+
+  fd = file_name_lookup (argv[1], O_READ | O_WRITE | O_CREAT, 0666);
+  if (fd == MACH_PORT_NULL)
+    error (1, errno, "file_name_lookup");
+
+  err = file_record_lock (fd, F_SETLK64, &lock, rendezvous, MACH_MSG_TYPE_MAKE_SEND);
+  if (err)
+    error (1, err, "file_record_lock");
+
+  pid = fork ();
+  if (pid == -1)
+    error (1, errno, "fork");
+
+  err = file_lock_stat (fd, &mine, &others);
+  if (err)
+    error (1, err, "file_lock_stat");
+
+  printf ("%s has a %s lock; Others have a %s lock.\n",
+	  pid ? "Parent" : "Child", lock2str (mine), lock2str (others));
+
+  mach_port_deallocate (mach_task_self (), fd);
+
+  return 0;
+}
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/locks.c
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/locks.c
@@ -0,0 +1,328 @@
+/* Test record locking.
+
+   Copyright (C) 2001, 2018-2019 Free Software Foundation, Inc.
+
+   Written by Neal H Walfield <n...@cs.uml.edu>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "../libfshelp/fshelp.h"
+#include "../libfshelp/rlock.h"
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "fs_U.h"
+
+#ifndef PEROPENS
+#define PEROPENS 10
+#endif
+
+struct rlock_box box;
+struct rlock_peropen peropens[PEROPENS];
+loff_t pointers[PEROPENS];
+loff_t file_size;
+
+struct command
+{
+  char *name;
+  int (*func)(char *cmds);
+  char *doc;
+};
+
+error_t cmd_help (char *);
+error_t cmd_comment (char *);
+error_t cmd_echo (char *);
+error_t cmd_lock (char *);
+error_t cmd_list (char *);
+error_t cmd_seek (char *);
+error_t cmd_exec (char *);
+
+struct command commands [] =
+  {
+    { "help", cmd_help, "Print this screen" },
+    { "#", cmd_comment, "Comment (Must _start_ the line)." },
+    { "echo", cmd_echo, "Echo the line." },
+    { "lock", cmd_lock,
+      "po start length type\n"
+      "\ttype = { F_UNLCK=0, F_RDLCK,=1, F_WRLCK=2 }" },
+    { "list", cmd_list, "list all locks' status" },
+    { "seek", cmd_seek, "PO1 ... Print the position of the given po.\n"
+      "\tPO1=N ... Seek a given po." },
+    { "exec", cmd_exec, "Execute a built in echoing the command."}
+  };
+
+error_t
+cmd_help (char *args)
+{
+  int i;
+  printf ("Commands:\n");
+  for (i = 0; i < sizeof (commands) / sizeof (struct command); i ++)
+    printf ("%s\t%s\n", commands[i].name, commands[i].doc);
+  return 0;
+}
+
+error_t
+cmd_comment (char *args)
+{
+  return 0;
+}
+
+error_t
+cmd_echo (char *args)
+{
+  printf ("%s", args);
+  return 0;
+}
+
+error_t
+cmd_lock (char *args)
+{
+  int po, type;
+  loff_t start, len;
+  struct flock64 lock;
+  mach_port_t rendezvous = MACH_PORT_NULL;
+  error_t err;
+
+  if (4 != sscanf (args, "%d %ld %ld %d", &po, (long*)&start, (long*)&len, &type))
+    {
+      printf ("Syntax error.\n");
+      return 0;
+    }
+
+  lock.l_type = type;
+  lock.l_whence = SEEK_CUR;
+  lock.l_start = (long)start;
+  lock.l_len = (long)len;
+
+  if (po < 0 || po >= PEROPENS)
+    {
+      printf ("Unknown peropen: %d.\n", po);
+      return 0;
+    }
+
+  switch (type)
+    {
+    case 0: lock.l_type = F_UNLCK; break;
+    case 1: lock.l_type = F_RDLCK; break;
+    case 2: lock.l_type = F_WRLCK; break;
+    default: printf ("Unknown type.\n"); return 0;
+    }
+
+  err= fshelp_rlock_tweak (&box, NULL, &peropens[po], O_RDWR,
+			   file_size, pointers[po], F_SETLK64,
+			   &lock, rendezvous);
+  if (! err)
+    {
+      char buf[10];
+      sprintf (buf, "%d\n", po);
+      cmd_list (buf);
+    }
+  return err;
+}
+
+error_t
+cmd_list (char *args)
+{
+  char *end;
+
+  void dump (int i)
+    {
+      struct rlock_list *l;
+
+      printf ("%3d:", i);
+      for (l = *peropens[i].locks; l; l = l->po.next)
+        {
+	  printf ("\tStart = %4ld; Length = %4ld; Type = ", (long)l->start, (long)l->len);
+	  switch (l->type)
+	    {
+	    case F_RDLCK: printf ("F_RDLCK"); break;
+	    case F_WRLCK: printf ("F_WRLCK"); break;
+	    case F_UNLCK: printf ("F_UNLCK"); break;
+	    default: printf ("UNKNOWN"); break;
+	    }
+	  printf ("\n");
+	}
+
+      if (*peropens[i].locks == NULL)
+	printf ("\n");
+    }
+
+  while (*args == ' ')
+    args ++;
+
+  if (*args == '\n' || *args == '\0')
+    {
+      int i;
+
+      for (i = 0; i < PEROPENS; i ++)
+	dump (i);
+      return 0;
+    }
+
+  while (1)
+    {
+      long int p = strtoll (args, &end, 0);
+      if (end == args)
+        {
+	  printf ("Syntax error.\n");
+	  return 0;
+	}
+
+      if (p < 0 || p > PEROPENS)
+	printf ("%3ld:\tOut of range.", p);
+      else
+	dump (p);
+
+      while (*end == ' ')
+	end ++;
+
+      if (*end == '\n' || *end == '\0')
+	return 0;
+      args = end;
+    }
+}
+
+error_t
+cmd_seek (char *args)
+{
+  char *end;
+  int p;
+
+  while (*args == ' ')
+    args ++;
+
+  if (*args == '\n' || *args == '\0')
+    {
+      int i;
+      for (i = 0; i < PEROPENS; i ++)
+        printf ("%3d: %ld\n", i, (long)pointers[i]);
+      return 0;
+    }
+
+  while (1)
+    {
+      int set = 0;
+      long seek_to = 0;
+
+      p = strtol (args, &end, 0);
+      if (end == args)
+        {
+	  printf ("Syntax error.\n");
+	  return 0;
+	}
+
+      if (*end == '=')
+        {
+	  set = 1;
+	  args = end + 1;
+	  seek_to = strtol (args, &end, 0);
+	  if (end == args)
+	    {
+	      printf ("Syntax error.\n");
+	      return 0;
+	    }
+	}
+
+      if (p < 0 || p > PEROPENS)
+	printf ("%3d: unknown peropen\n", p);
+      else
+        {
+          printf ("%3d: %ld", p, (long)pointers[p]);
+	  if (set)
+	    printf (" => %ld\n", (long)(pointers[p] = seek_to));
+	  else
+	    printf ("\n");
+	}
+
+      while (*end == ' ')
+	end ++;
+      if (*end == '\0' || *end == '\n')
+        return 0;
+      args = end;
+    }
+}
+
+error_t
+interpret (char *buffer)
+{
+  int i;
+
+  while (*buffer == ' ')
+    buffer ++;
+
+  if (*buffer == '\n')
+    return 0;
+
+  for (i = 0; i < sizeof (commands) / sizeof (struct command); i ++)
+  if (strncmp (commands[i].name, buffer, strlen (commands[i].name)) == 0)
+    {
+      error_t err;
+      err = commands[i].func (buffer + strlen (commands[i].name) + 1);
+      if (err)
+	printf ("%s\n", strerror (err));
+      return err;
+    }
+
+  printf ("Unknown command.\n");
+  return 0;
+}
+
+error_t
+cmd_exec (char *arg)
+{
+  printf ("%s", arg);
+  interpret (arg);
+  return 0;
+}
+
+int main (int argc, char *argv[])
+{
+  int i;
+
+  if (argc != 1)
+    {
+      printf ("Usage: %s\n"
+	      "\tType `help' at the prompt.\n"
+	      "\tUsed to test the record locking functions in libfshelp\n",
+	      argv[0]);
+      return 1;
+    }
+
+  fshelp_rlock_init (&box);
+  for (i = 0; i < PEROPENS; i ++)
+    fshelp_rlock_po_init (&peropens[i]);
+
+  while (! feof (stdin))
+    {
+      char b[1024];
+
+      printf ("> ");
+      fflush (stdout);
+
+      if (! fgets (b, sizeof (b), stdin))
+	{
+	  if (feof (stdin))
+	    break;
+	  else
+	    continue;
+	}
+
+      interpret (b);
+    }
+
+  printf ("\n");
+  return 0;
+}
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/locks-tests
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/locks-tests
@@ -0,0 +1,585 @@
+echo Legend:
+echo +   => Shared region
+echo x   => Exclusive region
+echo ' ' => Unlocked region
+echo .   => Clearing region
+echo []  => Start/End of a region
+echo After each lock command, the proposed region is shown followed
+echo by the result of applying it.
+echo * Established region wraps new region
+echo ** Both boundaries align
+echo [
+exec lock 0 1 10 1
+echo   [+++++++++++++]
+echo [ [+++++++++++++]
+exec lock 0 1 10 1
+echo   [+++++++++++++]
+echo [ [+++++++++++++]
+exec lock 0 1 10 2
+echo   [xxxxxxxxxxxxx]
+echo [ [xxxxxxxxxxxxx]
+exec lock 0 1 10 1
+echo   [+++++++++++++]
+echo [ [xxxxxxxxxxxxx]
+exec lock 0 1 10 2
+echo   [xxxxxxxxxxxxx]
+echo [ [xxxxxxxxxxxxx]
+exec lock 0 1 10 0
+echo   [.............]
+echo [
+exec lock 0 10 0 1
+echo         [++++++++
+echo [       [++++++++
+exec lock 0 10 0 1
+echo         [++++++++
+echo [       [++++++++
+exec lock 0 10 0 2
+echo         [xxxxxxxx
+echo [       [xxxxxxxx
+exec lock 0 10 0 2
+echo         [xxxxxxxx
+echo [       [xxxxxxxx
+exec lock 0 10 0 1
+echo         [++++++++
+echo [       [xxxxxxxx
+exec lock 0 10 0 0
+echo         [........
+echo [
+echo ** Left boundaries align
+exec lock 0 1 10 1
+echo   [+++++++++++]
+echo [ [+++++++++++]
+exec lock 0 1 5 1
+echo   [+++++]
+echo [ [+++++++++++]
+exec lock 0 1 5 2
+echo   [xxxxx]
+echo [ [xxxxx][++++]
+exec lock 0 1 3 1
+echo   [++]
+echo [ [xxxxx][++++]
+exec lock 0 1 10 0
+echo   [............
+echo [
+exec lock 0 1 10 1
+echo   [+++++++++++]
+echo [ [+++++++++++]
+exec lock 0 1 9 2
+echo   [xxxxxxxx]
+echo [ [xxxxxxxx][+]
+exec lock 0 1 5 0
+echo   [...]
+echo [      [***][+]
+exec lock 0 6 3 0
+echo        [.]
+echo [         [*][+]
+exec lock 0 9 1 0
+echo          [.]
+echo [           [+]
+exec lock 0 10 1 0
+echo             [.]
+echo [
+exec lock 0 1 0 1
+echo   [++++++++++++
+echo [ [++++++++++++
+exec lock 0 1 5 1
+echo   [++++]
+echo [ [++++++++++++
+exec lock 0 1 5 2
+echo   [xxxx]
+echo [ [xxxx][++++++
+exec lock 0 1 0 0
+echo   [............
+echo [
+exec lock 0 5 0 2
+echo     [xxxxxxxxxx
+echo [   [xxxxxxxxxx
+exec lock 0 5 5 1
+echo     [++++]
+echo [   [xxxxxxxxxx
+exec lock 0 5 0 1
+echo     [++++++++++
+echo [   [xxxxxxxxxx
+exec lock 0 0 0 0
+echo [..............
+echo [
+echo ** Common right side
+exec lock 0 5 5 1
+echo       [+++++]
+echo [     [+++++]
+exec lock 0 9 1 1
+echo           [+]
+echo [     [+++++]
+exec lock 0 9 1 2
+echo           [x]
+echo [     [++][x]
+exec lock 0 5 4 2
+echo       [xx]
+echo [     [xxxxx]
+exec lock 0 8 2 2
+echo           [x]
+echo [     [xxxxx]
+exec lock 0 9 1 0
+echo           [.]
+echo [     [xxx]
+exec lock 0 5 4 0
+echo       [...]
+echo [
+exec lock 0 5 0 1
+echo     [++++++++++
+echo [   [++++++++++
+exec lock 0 10 0 1
+echo          [+++++
+echo [   [++++++++++
+exec lock 0 10 0 2
+echo          [xxxxx
+echo [   [+++][xxxxx
+exec lock 0 5 0 0
+echo     [..........
+echo [
+echo ** Completely interior
+exec lock 0 5 10 1
+echo      [++++++++]
+echo [    [++++++++]
+exec lock 0 6 8 1
+echo       [++++++]
+echo [    [++++++++]
+exec lock 0 8 3 1
+echo         [+]
+echo [    [++++++++]
+exec lock 0 8 3 2
+echo         [x]
+echo [    [+][x][++]
+exec lock 0 12 1 2
+echo             x
+echo [    [++xxx+x+]
+exec lock 0 6 8 0
+echo       [......]
+echo [    [+]    [+]
+exec lock 0 0 0 0
+echo [..............
+echo [
+exec lock 0 5 0 1
+echo      [+++++++++
+echo [    [+++++++++
+exec lock 0 10 0 1
+echo           [++++
+echo [    [+++++++++
+exec lock 0 10 0 2
+echo           [xxxx
+echo [    [+++][xxxx
+exec lock 0 11 0 0
+echo             [..
+echo [    [+++][x]
+exec lock 0 6 0 0
+echo        [.......
+echo [    [+]
+exec lock 0 5 0 0
+echo      [.........
+echo [
+exec lock 0 10 0 1
+echo          [+++++
+echo [        [+++++
+exec lock 0 11 0 1
+echo           [+]
+echo [        [+++++
+exec lock 0 11 0 1
+echo           [+]
+echo [        [+++++
+exec lock 0 11 1 2
+echo           [x]
+echo [        [+x+++
+exec lock 0 13 0 1
+echo             [+]
+echo [        [+x+++
+exec lock 0 10 0 0
+echo          [.....
+echo [
+echo * We wrap the locked region
+echo ** Left boundaries align
+exec lock 0 1 10 1
+echo  [++++]
+echo [[++++]
+exec lock 0 1 15 1
+echo  [++++++++]
+echo [[++++++++]
+exec lock 0 1 16 1
+echo  [+++++++++]
+echo [[+++++++++]
+exec lock 0 1 20 2
+echo  [xxxxxxxxxxxxx]
+echo [[xxxxxxxxxxxxx]
+exec lock 0 1 30 1
+echo  [+++++++++++++++++++]
+echo [[xxxxxxxxxxxxx][++++]
+exec lock 0 22 11 2
+echo                   [xxx]
+echo [[xxxxxxxxxxxxx][+][xx]
+exec lock 0 1 40 0
+echo  [.........................]
+echo [
+exec lock 0 1 0 1
+echo  [++++++++++
+echo [[++++++++++
+exec lock 0 1 0 1
+echo  [++++++++++
+echo [[++++++++++
+exec lock 0 1 0 2
+echo  [xxxxxxxxxx
+echo [[xxxxxxxxxx
+exec lock 0 0 0 0
+echo [...........
+echo [
+exec lock 0 1 0 1
+echo  [++++++++++
+echo [[++++++++++
+exec lock 0 10 0 1
+echo       [+++++
+echo [[++++++++++
+exec lock 0 10 0 2
+echo       [xxxxx
+echo [[+++][xxxxx
+exec lock 0 0 0 0
+echo [...........
+echo [
+echo ** Right boundaries align
+exec lock 0 5 10 1
+echo     [++++++++]
+echo [   [++++++++]
+exec lock 0 4 11 1
+echo    [+++++++++]
+echo [  [+++++++++]
+exec lock 0 3 12 2
+echo   [xxxxxxxxxx]
+echo [ [xxxxxxxxxx]
+exec lock 0 0 15 2
+echo [xxxxxxxxxxxx]
+echo [xxxxxxxxxxxx]
+exec lock 0 0 0 0
+echo [.............
+echo [
+exec lock 0 5 0 1
+echo      [++++++++
+echo [    [++++++++
+exec lock 0 4 0 1
+echo     [+++++++++
+echo [   [+++++++++
+exec lock 0 3 0 2
+echo    [xxxxxxxxxx
+echo [  [xxxxxxxxxx
+exec lock 0 2 0 2
+echo   [xxxxxxxxxxx
+echo [ [xxxxxxxxxxx
+exec lock 0 0 0 2
+echo [xxxxxxxxxxxxx
+echo [xxxxxxxxxxxxx
+exec lock 0 0 0 0
+echo [.............
+echo [
+echo ** Consume locked region
+exec lock 0 5 10 1
+echo      [++++++++]
+echo [    [++++++++]
+exec lock 0 4 12 1
+echo     [++++++++++]
+echo [   [++++++++++]
+exec lock 0 2 16 1
+echo   [++++++++++++++]
+echo [ [++++++++++++++]
+exec lock 0 1 18 2
+echo  [xxxxxxxxxxxxxxxx]
+echo [[xxxxxxxxxxxxxxxx]
+exec lock 0 0 24 2
+echo [xxxxxxxxxxxxxxxxxxxxx]
+echo [xxxxxxxxxxxxxxxxxxxxx]
+exec lock 0 0 30 0
+echo [.........................]
+echo [
+exec lock 0 5 3 1
+echo      [++]
+echo [    [++]
+exec lock 0 10 5 1
+echo            [++++]
+echo [    [++]  [++++]
+exec lock 0 20 5 2
+echo                      [xxxx]
+echo [    [++]  [++++]    [xxxx]
+exec lock 0 4 30 2
+echo     [xxxxxxxxxxxxxxxxxxxxxxxxxx]
+echo [   [xxxxxxxxxxxxxxxxxxxxxxxxxx]
+exec lock 0 1 35 1
+echo   [++++++++++++++++++++++++++++++]
+echo [ [+[xxxxxxxxxxxxxxxxxxxxxxxxxx]+]
+exec lock 0 0 40 1
+echo [+++++++++++++++++++++++++++++++++++]
+echo [++][xxxxxxxxxxxxxxxxxxxxxxxxxx][+++]
+exec lock 0 0 0 0
+echo [....................................
+echo [
+exec lock 0 5 5 1
+echo      [+++]
+echo [    [+++]
+exec lock 0 4 0 1
+echo     [++++++]
+echo [   [++++++]
+exec lock 0 4 0 0
+echo     [..........
+echo [
+exec lock 0 5 3 1
+echo      [++]
+echo [    [++]
+exec lock 0 10 5 1
+echo              [++++]
+echo [    [++]    [++++]
+exec lock 0 0 0 1
+echo [++++++++++++++++++++
+echo [++++++++++++++++++++
+exec lock 0 0 0 0
+echo [....................
+echo [
+exec lock 0 5 3 1
+echo      [++]
+echo [    [++]
+exec lock 0 10 3 1
+echo             [++]
+echo [    [++]   [++]
+exec lock 0 4 0 1
+echo     [++++++++++++++
+echo [   [++++++++++++++
+exec lock 0 10 3 2
+echo             [**]
+echo [   [++++++][**][++
+exec lock 0 0 0 2
+echo [xxxxxxxxxxxxxxxxxx
+echo [xxxxxxxxxxxxxxxxxx
+exec lock 0 0 0 0
+echo [..................
+echo [
+echo * Our start is within the locked region or one byte after and our
+echo   end is after the end of the locked region.
+echo ** The regions are the same type: Merge into a single large region
+exec lock 0 5 5 1
+echo      [+++]
+echo [    [+++]
+exec lock 0 6 5 1
+echo       [+++]
+echo [    [++++]
+exec lock 0 8 8 1
+echo         [++++++]
+echo [    [+++++++++]
+exec lock 0 16 4 1
+echo                 [++]
+echo [    [+++++++++++++]
+exec lock 0 20 0 1
+echo                     [+++
+echo [    [++++++++++++++++++
+exec lock 0 5 16 0
+echo      [..............]
+echo [                    [+++
+exec lock 0 20 0 0
+echo                      [...
+echo [
+exec lock 0 6 6 2
+echo       [xxxx]
+echo [     [xxxx]
+exec lock 0 7 7 2
+echo        [xxxxx]
+echo [     [xxxxxx]
+exec lock 0 14 7 2
+echo               [xxxxx]
+echo [     [xxxxxxxxxxxxx]
+exec lock 0 21 0 2
+echo                      [xx
+echo [     [xxxxxxxxxxxxxxxxx
+exec lock 0 6 0 0
+echo       [.................
+echo [
+echo ** Different types just after the end of the locked region
+exec lock 0 1 3 1
+echo  [++]
+echo [[++]
+exec lock 0 4 3 2
+echo      [xx]
+echo [[++][xx]
+exec lock 0 7 3 1
+echo          [++]
+echo [[++][xx][++]
+exec lock 0 10 0 2
+echo              [xxx
+echo [[++][xx][++][xxx
+exec lock 0 5 0 0
+echo       [.........
+echo [[++]x
+exec lock 0 5 0 1
+echo       [+++
+echo [[++]x[+++
+exec lock 0 1 0 0
+echo  [...
+echo [
+echo ** New region consumes the intersection.
+exec lock 0 5 5 1
+echo      [+++]
+echo [    [+++]
+exec lock 0 8 6 2
+echo          [xxx]
+echo [    [++][xxx]
+exec lock 0 6 0 2
+echo         [xxxxxx
+echo [    [+][xxxxxx
+exec lock 0 5 0 0
+echo      [.........
+echo [
+echo ** New region is dominated
+exec lock 0 5 5 2
+echo      [xxx]
+echo [    [xxx]
+exec lock 0 8 6 1
+echo         [++++]
+echo [    [xxx][++]
+exec lock 0 6 0 1
+echo        [++++++
+echo [    [xxx][+++
+exec lock 0 5 0 0
+echo      [........
+echo [
+echo * Our start falls before the locked region.  Our end falls just
+echo   before or with in the region (although we do not consume it)
+echo ** The regions are the same type: Merge into a single large region
+exec lock 0 10 5 1
+echo           [+++]
+echo [         [+++]
+exec lock 0 5 5 1
+echo      [+++]
+echo [    [++++++++]
+exec lock 0 4 4 1
+echo     [++]
+echo [   [+++++++++]
+exec lock 0 0 10 1
+echo [+++++++++]
+echo [+++++++++++++]
+exec lock 0 0 15 0
+echo [...............]
+echo [
+exec lock 0 10 0 1
+echo           [++++
+echo [         [++++
+exec lock 0 5 5 1
+echo      [+++]
+echo [    [+++++++++
+exec lock 0 4 1 1
+echo     +
+echo [   [++++++++++
+exec lock 0 0 0 1
+echo [++++++++++++++
+echo [++++++++++++++
+exec lock 0 0 0 0
+echo [....
+echo [
+exec lock 0 10 5 2
+echo           [xxx]
+echo [         [xxx]
+exec lock 0 5 5 2
+echo      [xxx]
+echo [    [xxxxxxxx]
+exec lock 0 4 4 2
+echo     [xx]
+echo [   [xxxxxxxxx]
+exec lock 0 0 10 2
+echo [xxxxxxxxx]
+echo [xxxxxxxxxxxxx]
+exec lock 0 0 15 0
+echo [...............]
+echo [
+exec lock 0 10 0 2
+echo           [xxxx
+echo [         [xxxx
+exec lock 0 5 5 2
+echo      [xxx]
+echo [    [xxxxxxxxx
+exec lock 0 4 1 2
+echo     x
+echo [   [xxxxxxxxxx
+exec lock 0 0 0 2
+echo [xxxxxxxxxxxxxx
+echo [xxxxxxxxxxxxxx
+exec lock 0 0 0 0
+echo [....
+echo [
+echo ** Different types just before the start of the locked region
+exec lock 0 5 5 1
+echo       [+++]
+echo [     [+++]
+exec lock 0 3 2 2
+echo    [x]
+echo [  [x][+++]
+exec lock 0 2 1 1
+echo   +
+echo [ +[x][+++]
+exec lock 0 1 0 2
+echo  [xxxx
+echo [[xxxx
+exec lock 0 0 1 1
+echo +
+echo +[xxxx
+exec lock 0 0 0 0
+echo [....
+echo [....
+exec lock 0 5 0 1
+echo      [++++
+echo [    [++++
+exec lock 0 0 5 2
+echo [xxxxxxxxx
+echo [xxxxxxxxx
+exec lock 0 0 0 0
+echo [....
+echo [
+echo ** New region consumes the intersection.
+exec lock 0 5 5 1
+echo      [+++]
+echo [    [+++]
+exec lock 0 4 3 2
+echo     [x]
+echo [   [x][+]
+exec lock 0 2 0 2
+echo    [xxxxxx
+echo [  [xxxxxx
+exec lock 0 0 0 0
+echo [....
+echo [
+exec lock 0 5 0 1
+echo      [++++++
+echo [    [++++++
+exec lock 0 4 5 2
+echo     [xxx]
+echo [   [xxx][++
+exec lock 0 4 0 0
+echo     [....
+echo [
+exec lock 0 5 0 1
+echo      [++++
+echo [    [++++
+exec lock 0 0 0 2
+echo [xxxxxxxxxx
+echo [xxxxxxxxxx
+exec lock 0 0 0 0
+echo [....
+echo [
+echo ** New region is dominated
+exec lock 0 5 5 2
+echo      [xxx]
+echo [    [xxx]
+exec lock 0 4 5 1
+echo     [+++]
+echo [   +[xxx]
+exec lock 0 0 0 0
+echo [...
+echo [
+exec lock 0 5 0 2
+echo     [xxxx
+echo [   [xxxx
+exec lock 0 0 0 1
+echo [++++++++
+echo [+++[xxxx
+exec lock 0 0 0 0
+echo [....
+echo [
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/race.c
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/race.c
@@ -0,0 +1,83 @@
+/* Test races in the record locking code.
+
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+   Written by Neal H Walfield <n...@cs.uml.edu>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <error.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "fs_U.h"
+#include <hurd.h>
+#include "io_U.h"
+
+int main (int argc, char **argv)
+{
+  error_t err;
+  struct flock64 lock;
+  mach_port_t rendezvous = MACH_PORT_NULL;
+  int fd;
+  int i;
+  uint v;
+  int blocked = 0;
+  char buf[10] = "";
+  char *bufp;
+
+  if (argc != 4)
+    error (1, 0, "Usage: %s file start len", argv[0]);
+
+  lock.l_whence = SEEK_SET;
+  lock.l_start = atoi (argv[2]);
+  lock.l_len = atoi (argv[3]);
+
+  fd = file_name_lookup (argv[1], O_READ | O_WRITE | O_CREAT, 0666);
+  if (fd == MACH_PORT_NULL)
+    error (1, errno, "file_name_lookup");
+
+  for (i = 0; i < 10000; i ++)
+    {
+      lock.l_type = F_WRLCK;
+      err = file_record_lock (fd, F_SETLK64, &lock, rendezvous, MACH_MSG_TYPE_MAKE_SEND);
+      if (err)
+        {
+	  blocked ++;
+          err = file_record_lock (fd, F_SETLKW64, &lock, rendezvous, MACH_MSG_TYPE_MAKE_SEND);
+	}
+      if (err)
+        error (1, err, "file_record_lock");
+
+      v = sizeof (buf);
+      bufp = buf;
+      io_read (fd, &bufp, &v, 0, v);
+
+      v = atoi (bufp);
+      sprintf (buf, "%d\n", v + 1);
+
+      v = 10;
+      io_write (fd, buf, sizeof (buf), 0, &v);
+      if (v == 0)
+        error (1, errno, "write (%d)", i);
+
+      lock.l_type = F_UNLCK;
+      file_record_lock (fd, F_SETLK64, &lock, rendezvous, MACH_MSG_TYPE_MAKE_SEND);
+    }
+
+  mach_port_deallocate (mach_task_self (), fd);
+
+  printf ("Was blocked %d times\n", blocked);
+  return 0;
+}
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/README.new_tests
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/README.new_tests
@@ -0,0 +1,146 @@
+File: README.new_tests
+
+C-code:
+=======
+test-fcntl.c
+test-lockf.c
+test-flock.c
+
+Compile:
+========
+gcc -g -Wall -D_FILE_OFFSET_BITS=64 -o test-fcntl test-fcntl.c
+gcc -g -Wall -D_FILE_OFFSET_BITS=64 -o test-lockf test-lockf.c
+gcc -g -Wall -D_FILE_OFFSET_BITS=64 -o test-flock test-flock.c
+
+./test-fcntl
+./test-fcntl: Usage: ./test-fcntl file [flags] [cmd] [len] [sleep_time]
+    file          : file name/device name
+    flags         : r (O_RDONLY) | w (O_WRONLY) | rw (O_RDWR)      : [rw]
+    cmd           : g (F_GETLK), s (F_SETLK), sw (F_SETLKW)        : [s]
+    lock.l_type   : rl (F_RDLCK), wl (F_WRLCK), ul [F_UNLCK]       : [ul]
+    lock.l_whence : ss (SEEK_SET), sc (SEEK_CUR), se (SEEK_END)    : [ss]
+    lock.l_start  : b <number>                                     : [b 0]
+    lock.l_len    : l <number>                                     : [l 0]
+    sleep_time    : st <number>                                    : [st 10]
+
+./test-lockf
+./test-lockf: Usage: ./test-lockf file [flags] [cmd] [len] [sleep_time]
+    file          : file name/device name
+    flags         : r (O_RDONLY) | w (O_WRONLY) | rw (O_RDWR)      : [w]
+    cmd           : x (F_LOCK), xt (F_TLOCK), u (F_ULOCK),
+                    t (F_TEST)                                     : [x]
+    len           : l <number>                                     : [0]
+    sleep_time    : st <number>                                    : [st 10]
+
+./test-flock
+./test-flock: Usage: ./test-flock file [flags] [operation] [sleep_time]
+    file          : file name/device name
+    flags         : r (O_RDONLY) | w (O_WRONLY) | rw (O_RDWR)      : [w]
+    operation     : s (LOCK_SH), x (LOCK_EX), u (LOCK_UN),
+                    sn (LOCK_SH | LOCK_UN), xn (LOCK_EX | LOCK_UN) : [s]
+    sleep_time    : st <number>                                    : [st 10]
+
+Results:
+========
+New version of file_record_lock:
+libdiskfs/file-lock.c(diskfs_S_file_lock): Commented out
+libnetfs/file-lock.c(netfs_S_file_lock): Commented out
+libtrivfs/file-lock.c(trivfs_S_file_lock): TODO: Add+comment out
+libtrivfs/make-peropen.c(trivfs_S_file_lock): FIXME: po->openmodes = O_RDWR;
+if (openstat & (O_RDONLY|O_WRONLY|O_EXEC)) openstat |= O_RDONLY|O_WRONLY;
+
+libfshelp/rlock-tweak.c(fshelp_rlock_tweak): Removed
+if (lock->l_type == F_RDLCK && !(open_mode & O_READ))
+  return EACCES;
+if (lock->l_type == F_WRLCK && !(open_mode & O_WRITE))
+  return EACCES;
+Added:
+/* From POSIX-1003.1: A request for an exclusive lock shall fail if
+   the file descriptor was not opened with write access. */
+if ((cmd == F_SETLK64 || cmd == F_SETLKW64 )
+    && lock->l_type == F_WRLCK && !(open_mode & O_WRITE))
+  return EBADF;
+
+test-fcntl:
+===========
+libdiskfs:
+----------
+
+touch foo
+./test-fcntl foo {r,w} g {rl,wl}
+./test-fcntl foo r {s,sw} wl
+./test-fcntl: fcntl: Bad file descriptor
+./test-fcntl foo r {s,sw} {rl,ul}
+
+T1: T2:
+./test-fcntl foo {r,w} {s,sw} {rl,wl}
+./test-fcntl foo {r,w} {s,sw} {rl,wl}
+
+libnetfs:
+---------
+Not applicable on GNU/Linux?
+
+settrans -c ftp: /hurd/hostmux /hurd/ftpfs /
+Check:
+file ftp:
+ftp:: directory
+ls ftp://ftp.gnu.org/
+less ftp://ftp.gnu.org/README
+
+./test-fcntl ftp://ftp.gnu.org/README r g {rl,wl}
+./test-fcntl ftp://ftp.gnu.org/README w g {rl,wl}
+./test-fcntl: open: Permission denied
+
+./test-fcntl ftp://ftp.gnu.org/README r {s,sw} {rl,ul}
+./test-fcntl ftp://ftp.gnu.org/README r {s,sw} wl
+./test-fcntl: fcntl: Bad file descriptor
+
+settrans -fg ftp:
+rm ftp:
+
+libtrivs:
+---------
+BUG: ./test-fcntl /dev/null r s wl
+GNU/Linux:
+./test-fcntl: fcntl: Bad file descriptor
+
+test-lockf:
+===========
+libdiskfs:
+----------
+touch foo
+./test-lockf foo {r,w} {x,xt,u,t}
+T1, T2:
+./test-lockf foo {r,w} {x,xt,u,t}
+
+libnetfs:
+---------
+
+libtrivfs:
+----------
+
+test-flock:
+===========
+libdiskfs:
+----------
+touch foo
+./test-flock foo {r,w} {s,x,u,sn,xn}
+
+GNU/Linux:
+./test-flock foo r x
+
+GNU/Hurd:
+./test-flock foo r {x,xn}
+./test-flock: flock: Bad file descriptor
+
+T1: ./test-flock foo w s,x
+T2: ./test-flock foo w x (waits for the first lock)
+
+libnetfs:
+---------
+
+libtrivfs:
+----------
+GNU/Hurd
+T1: ./test-flock /dev/null w s,x
+BUG: T2: ./test-flock /dev/null w x (does not wait for the first lock)
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/test-fcntl.c
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/test-fcntl.c
@@ -0,0 +1,273 @@
+/* test-fcntl.c: Test advisory open file record locks, see fcntl(2)
+   Options: <see below>
+
+   Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+   Written by Svante Signell <svante.sign...@gmail.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 3, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/file.h>
+
+/* Parse args */
+int parse_args (int argc, char **argv, char **file_name,
+		int *flags, char **flagsc,
+		int *cmd, char **cmdc,
+		struct flock *lock,
+		char **l_typec, char **l_whencec,
+		int *sleep_time)
+{
+  int i, tmp;
+  char *str, *endptr;
+
+  if (argc < 2)
+    error (1, 0, "Usage: %s file [flags] [cmd] [len] [sleep_time]\n\
+    file          : file name/device name\n\
+    flags         : r (O_RDONLY) | w (O_WRONLY) | rw (O_RDWR)      : [rw]\n\
+    cmd           : g (F_GETLK), s (F_SETLK), sw (F_SETLKW)        : [s]\n\
+    lock.l_type   : rl (F_RDLCK), wl (F_WRLCK), ul [F_UNLCK]       : [ul]\n\
+    lock.l_whence : ss (SEEK_SET), sc (SEEK_CUR), se (SEEK_END)    : [ss]\n\
+    lock.l_start  : b <number>                                     : [b 0]\n\
+    lock.l_len    : l <number>                                     : [l 0]\n\
+    sleep_time    : st <number>                                    : [st 10]\n",
+    argv[0]);
+
+  *file_name = argv[1];
+  for (i = 2; i < argc; i++)
+    {
+      str = argv[i];
+      if (strncmp (str, "r", 2) == 0)
+	{
+	  *flags = O_RDONLY;
+	  *flagsc = "O_RDONLY";
+	  continue;
+	}
+      if (strncmp (str, "w", 2) == 0)
+	{
+	  *flags = O_WRONLY;
+	  *flagsc = "O_WRONLY";
+	  continue;
+	}
+      if (strncmp (str, "rw", 2) == 0)
+	{
+	  *flags = O_RDWR;
+	  *flagsc = "O_RDWR";
+	  continue;
+	}
+      if (strncmp (str, "s", 2) == 0)
+	{
+      	  *cmd = F_SETLK;
+	  *cmdc = "F_SETLK";
+	  continue;
+	}
+      if (strncmp (str, "sw", 2) == 0)
+	{
+	  *cmd = F_SETLKW;
+	  *cmdc = "F_SETLKW";
+	  continue;
+	}
+      if (strncmp (str, "g", 2) == 0)
+	{
+	  *cmd = F_GETLK;
+	  *cmdc = "F_GETLK";
+	  continue;
+	}
+      if (strncmp (str, "rl", 2) == 0)
+	{
+	  lock->l_type = F_RDLCK;
+	  *l_typec = "F_RDLCK";
+	  continue;
+	}
+      if (strncmp (str, "wl", 2) == 0)
+	{
+	  lock->l_type = F_WRLCK;
+	  *l_typec = "F_WRLCK";
+	  continue;
+	}
+      if (strncmp (str, "ul", 2) == 0)
+	{
+	  lock->l_type = F_UNLCK;
+	  *l_typec = "F_UNLCK";
+	  continue;
+	}
+      if (strncmp (str, "ss", 2) == 0)
+	{
+	  lock->l_whence = SEEK_SET;
+	  *l_whencec = "SEEK_SET";
+	  continue;
+	}
+      if (strncmp (str, "sc", 2) == 0)
+	{
+	  lock->l_whence = SEEK_CUR;
+	  *l_whencec = "SEEK_CUR";
+	  continue;
+	}
+      if (strncmp (str, "se", 2) == 0)
+	{
+	  lock->l_whence = SEEK_END;
+	  *l_whencec = "SEEK_END";
+	  continue;
+	}
+      if (strncmp (str, "b", 2) == 0)
+	{
+	  str = argv[++i];
+	  if (str)
+	    {
+	      errno = 0;
+	      tmp = strtol (str, &endptr, 10);
+	      if (tmp == 0 && errno != 0)
+		error (1, errno, "%s", str);
+	      if (endptr == str)
+		error (1, EINVAL, "%s", str);
+	      lock->l_start = tmp;
+	    }
+	  else
+	    error (1, EINVAL, "%s", str);
+	  continue;
+	}
+      if (strncmp (str, "l", 2) == 0)
+	{
+	  str = argv[++i];
+	  if (str)
+	    {
+	      errno = 0;
+	      tmp = strtol (str, &endptr, 10);
+	      if (tmp == 0 && errno != 0)
+		error (1, errno, "%s", str);
+	      if (endptr == str)
+		error (1, EINVAL, "%s", str);
+	      lock->l_len = tmp;
+	    }
+	  else
+	    error (1, EINVAL, "%s", str);
+	  continue;
+	}
+      if (strncmp (str, "st", 2) == 0)
+	{
+	  str = argv[++i];
+	  if (str)
+	    {
+	      errno = 0;
+	      tmp = strtol (str, &endptr, 10);
+	      if (tmp == 0 && errno != 0)
+		error (1, errno, "%s", str);
+	      if (endptr == str)
+		error (1, EINVAL, "%s", str);
+	      *sleep_time = tmp;
+	    }
+	  else
+	    error (1, EINVAL, "%s", str);
+	  continue;
+	}
+      error (1, EINVAL, "%s", str);
+    }
+
+  return 0;
+}
+
+int main (int argc, char **argv)
+{
+#ifdef __GNU__
+  error_t err;
+#else
+  int err;
+#endif
+  int fd, ret = -1;
+  char *file_name = NULL;
+  int flags = O_RDWR;
+  char *flagsc = "O_RDWR";
+  char *old_l_typec;
+  int old_l_type, old_l_pid;
+  int cmd = F_SETLK;
+  char *cmdc = "F_SETLK";
+  struct flock lock = {
+    F_UNLCK,
+    SEEK_SET,
+    0,
+    0,
+    123456};
+  char *l_typec = "F_UNLCK";
+  char *l_whencec = "SEEK_SET";
+  int sleep_time = 10;
+
+  ret = parse_args (argc, argv, &file_name,
+		    &flags, &flagsc,
+		    &cmd, &cmdc,
+		    &lock,
+		    &l_typec, &l_whencec,
+		    &sleep_time);
+
+#ifdef __GNU__
+  printf ("test-fcntl: GNU/Hurd\n");
+#else
+  printf ("test-fcntl: GNU/Linux\n");
+#endif
+  printf ("test-fcntl: [PID]=%d\n", getpid());
+  printf ("file = '%s', flags = %s\n", file_name, flagsc);
+  fd = open (file_name, flags);
+  if (fd < 0)
+    error (1, errno, "open");
+  printf ("Opening '%s', fd = %d, ", file_name, fd);
+  printf ("cmd = %s\n ", cmdc);
+  printf("lock = {l_type,  l_whence, l_start, l_len, l_pid} =\n");
+#ifdef __GNU__
+  printf ("        {%s, %s, %lld,       %lld,     %d}\n",
+#else
+  printf ("        {%s, %s, %ld,       %ld,     %d}\n",
+#endif
+         l_typec, l_whencec, lock.l_start, lock.l_len, lock.l_pid);
+
+  old_l_type = lock.l_type;
+  old_l_typec = l_typec;
+  old_l_pid = lock.l_pid;
+
+  printf ("Requesting lock\n");
+  err = fcntl (fd, cmd, &lock);
+  if (err)
+    error (1, errno, "fcntl");
+
+  if (old_l_type != lock.l_type)
+    if (lock.l_type == F_UNLCK)
+      {
+	l_typec = "F_UNLCK";
+	printf("[PID=%ld] Lock can be placed\n", (long) getpid());
+	printf ("old_l_type = %s, l_type = %s\n", old_l_typec, l_typec);
+	return ret;
+      }
+      if (old_l_pid != lock.l_pid)
+    {
+      printf("[PID=%ld] Denied by %s lock on %lld:%lld "
+	     "(held by PID %ld)\n", (long) getpid(),
+	     (lock.l_type == F_RDLCK) ? "READ" : "WRITE",
+	     (long long) lock.l_start,
+	     (long long) lock.l_len, (long) lock.l_pid);
+      return ret;
+    }
+  printf ("Got lock: sleep_time = %d seconds\n", sleep_time);
+  sleep (sleep_time);
+  printf ("Closing '%s'\n", file_name);
+  close (fd);
+
+  return ret;
+}
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/test-lockf.c
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/test-lockf.c
@@ -0,0 +1,184 @@
+/* test-lockf.c: Test advisory open file record locks:
+   lockf(3) is an interface on top of fcntl(2) locking.
+   Options: <see below>
+
+   Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+   Written by Svante Signell <svante.sign...@gmail.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 3, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/file.h>
+
+/* Parse args */
+int parse_args (int argc, char **argv, char **file_name,
+		int *flags, char **flagsc,
+		int *cmd, char **cmdc,
+		off_t *len, int *sleep_time)
+{
+  int i, tmp;
+  char *str, *endptr;
+
+  if (argc < 2)
+    error (1, 0, "Usage: %s file [flags] [cmd] [len] [sleep_time]\n\
+    file          : file name/device name\n\
+    flags         : r (O_RDONLY) | w (O_WRONLY) | rw (O_RDWR)      : [w]\n\
+    cmd           : x (F_LOCK), xt (F_TLOCK), u (F_ULOCK),\n\
+                    t (F_TEST)                                     : [x]\n\
+    len           : l <number>                                     : [0]\n\
+    sleep_time    : st <number>                                    : [st 10]\n",
+    argv[0]);
+
+  *file_name = argv[1];
+  for (i = 2; i < argc; i++)
+    {
+      str = argv[i];
+      if (strncmp (str, "r", 2) == 0)
+	{
+	  *flags = O_RDONLY;
+	  *flagsc = "O_RDONLY";
+	  continue;
+	}
+      if (strncmp (str, "w", 2) == 0)
+	{
+	  *flags = O_WRONLY;
+	  *flagsc = "O_WRONLY";
+	  continue;
+	}
+      if (strncmp (str, "rw", 2) == 0)
+	{
+	  *flags = O_RDWR;
+	  *flagsc = "O_RDWR";
+	  continue;
+	}
+      if (strncmp (str, "x", 2) == 0)
+	{
+      	  *cmd = F_LOCK;
+	  *cmdc = "F_LOCK";
+	  continue;
+	}
+      if (strncmp (str, "xt", 2) == 0)
+	{
+	  *cmd = F_TLOCK;
+	  *cmdc = "F_TLOCK";
+	  continue;
+	}
+      if (strncmp (str, "u", 2) == 0)
+	{
+	  *cmd = F_ULOCK;
+	  *cmdc = "F_LOCK";
+	  continue;
+	}
+      if (strncmp (str, "t", 2) == 0)
+	{
+	  *cmd = F_TEST;
+	  *cmdc = "F_TEST";
+	  continue;
+	}
+      if (strncmp (str, "l", 2) == 0)
+	{
+	  str = argv[++i];
+	  if (str)
+	    {
+	      errno = 0;
+	      tmp = strtol (str, &endptr, 10);
+	      if (tmp == 0 && errno != 0)
+		error (1, errno, "%s", str);
+	      if (endptr == str)
+		error (1, EINVAL, "%s", str);
+	      *len = tmp;
+	    }
+	  else
+	    error (1, EINVAL, "%s", str);
+	  continue;
+	}
+      if (strncmp (str, "st", 2) == 0)
+	{
+	  str = argv[++i];
+	  if (str)
+	    {
+	      errno = 0;
+	      tmp = strtol (str, &endptr, 10);
+	      if (tmp == 0 && errno != 0)
+		error (1, errno, "%s", str);
+	      if (endptr == str)
+		error (1, EINVAL, "%s", str);
+	      *sleep_time = tmp;
+	    }
+	  else
+	    error (1, EINVAL, "%s", str);
+	  continue;
+	}
+      error (1, EINVAL, "%s", str);
+    }
+
+  return 0;
+}
+
+int main (int argc, char **argv)
+{
+#ifdef __GNU__
+  error_t err;
+#else
+  int err;
+#endif
+  int fd, ret = -1;
+  char *file_name = NULL;
+  int flags = O_WRONLY;
+  char *flagsc = "O_WRONLY";
+  int cmd = F_LOCK;
+  char *cmdc = "F_LOCK";
+  off_t len = 0;
+  int sleep_time = 10;
+
+  ret = parse_args (argc, argv, &file_name,
+		    &flags, &flagsc,
+		    &cmd, &cmdc,
+		    &len, &sleep_time);
+
+#ifdef __GNU__
+  printf ("test-lockf: GNU/Hurd\n");
+#else
+  printf ("test-lockf: GNU/Linux\n");
+#endif
+
+  printf ("file = '%s', flags = %s\n", file_name, flagsc);
+  fd = open (file_name, flags);
+  if (fd < 0)
+    error (1, errno, "open");
+  printf ("Opening '%s', fd = %d, ", file_name, fd);
+  printf ("cmd = %s, len = %ld\n", cmdc, len);
+  printf ("Requesting lock\n");
+  err = lockf (fd, cmd, len);
+  if (err)
+    error (1, errno, "lockf");
+
+  printf ("Got lock: sleep_time = %d seconds\n", sleep_time);
+  sleep (sleep_time);
+
+  printf ("Closing '%s'\n", file_name);
+  close (fd);
+
+  return ret;
+}
Index: hurd-0.9.git20190331-8.2/libfshelp-tests/test-flock.c
===================================================================
--- /dev/null
+++ hurd-0.9.git20190331-8.2/libfshelp-tests/test-flock.c
@@ -0,0 +1,170 @@
+/* test-flock.c: Test advisory open file locks, see flock(2)
+   Options: <see below>
+
+   Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+   Written by Svante Signell <svante.sign...@gmail.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 3, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/file.h>
+
+/* Parse args */
+int parse_args (int argc, char **argv, char **file_name,
+		int *flags, char **flagsc,
+		int *op, char **opc,
+		int *sleep_time)
+{
+  int i, tmp;
+  char *str, *endptr;
+
+  if (argc < 2)
+    error (1, 0, "Usage: %s file [flags] [operation] [sleep_time]\n\
+    file          : file name/device name\n\
+    flags         : r (O_RDONLY) | w (O_WRONLY) | rw (O_RDWR)      : [w]\n\
+    operation     : s (LOCK_SH), x (LOCK_EX), u (LOCK_UN),\n\
+                    sn (LOCK_SH | LOCK_UN), xn (LOCK_EX | LOCK_UN) : [s]\n\
+    sleep_time    : st <number>                                    : [st 10]\n",
+    argv[0]);
+
+  *file_name = argv[1];
+  for (i = 2; i < argc; i++)
+    {
+      str = argv[i];
+      if (strncmp (str, "r", 2) == 0)
+	{
+	  *flags = O_RDONLY;
+	  *flagsc = "O_RDONLY";
+	  continue;
+	}
+      if (strncmp (str, "w", 2) == 0)
+	{
+	  *flags = O_WRONLY;
+	  *flagsc = "O_WRONLY";
+	  continue;
+	}
+      if (strncmp (str, "rw", 2) == 0)
+	{
+	  *flags = O_RDWR;
+	  *flagsc = "O_RDWR";
+	  continue;
+	}
+      if (strncmp (str, "s", 2) == 0)
+	{
+      	  *op = LOCK_SH;
+	  *opc = "LOCK_SH";
+	  continue;
+	}
+      if (strncmp (str, "sn", 2) == 0)
+	{
+	  *op = LOCK_SH | LOCK_NB;
+	  *opc = "LOCK_SH | LOCK_NB";
+	  continue;
+	}
+      if (strncmp (str, "x", 2) == 0)
+	{
+	  *op = LOCK_EX;
+	  *opc = "LOCK_EX";
+	  continue;
+	}
+      if (strncmp (str, "xn", 2) == 0)
+	{
+	  *op = LOCK_EX | LOCK_NB;
+	  *opc = "LOCK_EX | LOCK_NB";
+	  continue;
+	}
+      if (strncmp (str, "u", 2) == 0)
+	{
+	  *op = LOCK_UN;
+	  *opc = "LOCK_UN";
+	  continue;
+	}
+      if (strncmp (str, "st", 2) == 0)
+	{
+	  str = argv[++i];
+	  if (str)
+	    {
+	      errno = 0;
+	      tmp = strtol (str, &endptr, 10);
+	      if (tmp == 0 && errno != 0)
+		error (1, errno, "%s", str);
+	      if (endptr == str)
+		error (1, EINVAL, "%s", str);
+	      *sleep_time = tmp;
+	    }
+	  else
+	    error (1, EINVAL, "%s", str);
+	  continue;
+	}
+      error (1, EINVAL, "%s", str);
+    }
+
+  return 0;
+}
+
+int main (int argc, char **argv)
+{
+#ifdef __GNU__
+  error_t err;
+#else
+  int err;
+#endif
+  int fd, ret = -1;
+  char *file_name = NULL;
+  int flags = O_RDONLY;
+  char *flagsc = "O_RDONLY";
+  int op = LOCK_SH;
+  char *opc = "LOCK_SH";
+  int sleep_time = 10;
+
+  ret = parse_args (argc, argv, &file_name,
+		    &flags, &flagsc,
+		    &op, &opc,
+		    &sleep_time);
+
+#ifdef __GNU__
+  printf ("test-flock: GNU/Hurd\n");
+#else
+  printf ("test-flock: GNU/Linux\n");
+#endif
+
+  printf ("file = '%s', flags = %s\n", file_name, flagsc);
+  fd = open (file_name, flags);
+  if (fd < 0)
+    error (1, errno, "open");
+  printf ("Opening '%s', fd = %d, ", file_name, fd);
+  printf ("operation = %s\n", opc);
+  printf ("Requesting lock\n");
+  err = flock (fd, op);
+  if (err)
+    error (1, errno, "flock");
+
+  printf ("Got lock: sleep_time = %d seconds\n", sleep_time);
+  sleep (sleep_time);
+
+  printf ("Closing '%s'\n", file_name);
+  close (fd);
+
+  return ret;
+}
REVERT!!
commit 346ef23f197a0c8ba807c344bd39101b711050ee
Author: Samuel Thibault <samuel.thiba...@ens-lyon.org>
Date:   Thu Nov 15 00:52:36 2018 +0100

    hurd: Fix F_*LK* fcntl with __USE_FILE_OFFSET64
    
    struct flock64 uses 64bit values. This introduces other values for F_GETLK,
    F_SETLK, F_SETLKW to distinguish between both.
    
            * sysdeps/mach/hurd/bits/fcntl.h (F_GETLK64, F_SETLK64, F_SETLKW64): New
            macros
            [__USE_FILE_OFFSET64] (F_GETLK, F_SETLK, F_SETLKW): Define to F_GETLK64,
            F_SETLK64, F_SETLKW64, respectively.
            * sysdeps/mach/hurd/f_setlk.c: New file.
            * sysdeps/mach/hurd/f_setlk.h: New file.
            * sysdeps/mach/hurd/Makefile [$(subdir) = io] (sysdeps_routines): Add
            f_setlk.
            * sysdeps/mach/hurd/fcntl.c: Include "f_setlk.h".h".
            (__libc_fcntl): Move non-flock operations to...
            * sysdeps/mach/hurd/vfcntl.c (__libc_vfcntl): ... New file.

--- a/sysdeps/mach/hurd/Makefile	2019-09-11 10:50:11.000000000 +0200
+++ b/sysdeps/mach/hurd/Makefile	2019-09-11 10:52:30.000000000 +0200
@@ -195,10 +195,6 @@
 sysdep_routines += cthreads
 endif
 
-ifeq (io, $(subdir))
-sysdep_routines += f_setlk
-endif
-
 ifeq ($(subdir),sunrpc)
 sysdep_headers += nfs/nfs.h
 endif
--- a/sysdeps/mach/hurd/bits/fcntl.h	2019-09-11 14:48:46.000000000 +0200
+++ b/sysdeps/mach/hurd/bits/fcntl.h	2019-09-11 14:50:24.000000000 +0200
@@ -1,5 +1,5 @@
 /* O_*, F_*, FD_* bit values for GNU.
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
+   Copyright (C) 1993-2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -163,18 +163,9 @@
 # define F_GETOWN	5	/* Get owner (receiver of SIGIO).  */
 # define F_SETOWN	6	/* Set owner (receiver of SIGIO).  */
 #endif
-#ifdef __USE_FILE_OFFSET64
-# define	F_GETLK		F_GETLK64
-# define	F_SETLK		F_SETLK64
-# define	F_SETLKW	F_SETLKW64
-#else
-# define	F_GETLK		7	/* Get record locking info.  */
-# define	F_SETLK		8	/* Set record locking info (non-blocking).  */
-# define	F_SETLKW	9	/* Set record locking info (blocking).  */
-#endif
-#define	F_GETLK64	10	/* Get record locking info.  */
-#define	F_SETLK64	11	/* Set record locking info (non-blocking).  */
-#define	F_SETLKW64	12	/* Set record locking info (blocking).  */
+#define	F_GETLK		7	/* Get record locking info.  */
+#define	F_SETLK		8	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW	9	/* Set record locking info (blocking).  */
 
 #ifdef __USE_XOPEN2K8
 # define F_DUPFD_CLOEXEC 1030	/* Duplicate, set FD_CLOEXEC on new one.  */
--- a/sysdeps/mach/hurd/f_setlk.c	2019-09-11 14:34:15.000000000 +0200
+++ /dev/null	2017-01-20 12:59:50.000000000 +0100
@@ -1,69 +0,0 @@
-/* f_setlk -- locking part of fcntl
-   Copyright (C) 2014-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <errno.h>
-
-/* XXX
-   We need new RPCs to support POSIX.1 fcntl file locking!!
-   For the time being we support the whole-file case only,
-   with all kinds of WRONG WRONG WRONG semantics,
-   by using flock.  This is definitely the Wrong Thing,
-   but it might be better than nothing (?).  */
-int
-__f_setlk (int fd, int type, int whence, __off64_t start, __off64_t len, int wait)
-{
-  int cmd = 0;
-
-  switch (type)
-    {
-    case F_RDLCK: cmd = LOCK_SH; break;
-    case F_WRLCK: cmd = LOCK_EX; break;
-    case F_UNLCK: cmd = LOCK_UN; break;
-    default:
-      errno = EINVAL;
-      return -1;
-    }
-
-  if (cmd != LOCK_UN && wait == 0)
-    cmd |= LOCK_NB;
-
-  switch (whence)
-    {
-    case SEEK_SET:
-      if (start == 0 && len == 0) /* Whole file request.  */
-	break;
-      /* It seems to be common for applications to lock the first
-	 byte of the file when they are really doing whole-file locking.
-	 So, since it's so wrong already, might as well do that too.  */
-      if (start == 0 && len == 1)
-	break;
-      /* FALLTHROUGH */
-    case SEEK_CUR:
-    case SEEK_END:
-      errno = ENOTSUP;
-      return -1;
-    default:
-      errno = EINVAL;
-      return -1;
-    }
-
-  return __flock (fd, cmd);
-}
--- a/sysdeps/mach/hurd/f_setlk.h	2019-01-31 17:45:36.000000000 +0100
+++ /dev/null	2017-01-20 12:59:50.000000000 +0100
@@ -1,23 +0,0 @@
-/* Copyright (C) 2014-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _F_SETLK_H
-#define _F_SETLK_H 1
-
-extern int __f_setlk (int fd, int type, int whence, __off64_t start, __off64_t len, int wait);
-
-#endif /* f_setlk.h */
--- a/sysdeps/mach/hurd/fcntl.c.orig	2019-01-31 17:45:36.000000000 +0100
+++ b/sysdeps/mach/hurd/fcntl.c	2019-09-11 11:12:34.000000000 +0200
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2019 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -21,7 +21,6 @@
 #include <hurd/fd.h>
 #include <stdarg.h>
 #include <sys/file.h>		/* XXX for LOCK_* */
-#include "f_setlk.h"
 
 /* Perform file control operations on FD.  */
 int
@@ -129,48 +128,56 @@
     case F_SETLK:
     case F_SETLKW:
       {
+	/* XXX
+	   We need new RPCs to support POSIX.1 fcntl file locking!!
+	   For the time being we support the whole-file case only,
+	   with all kinds of WRONG WRONG WRONG semantics,
+	   by using flock.  This is definitely the Wrong Thing,
+	   but it might be better than nothing (?).  */
 	struct flock *fl = va_arg (ap, struct flock *);
-	int wait = 0;
 	va_end (ap);
 	switch (cmd)
 	  {
 	  case F_GETLK:
 	    errno = ENOSYS;
 	    return -1;
-	  case F_SETLKW:
-	    wait = 1;
-	    /* FALLTHROUGH */
 	  case F_SETLK:
-	    return __f_setlk (fd, fl->l_type, fl->l_whence,
-			      fl->l_start, fl->l_len, wait);
+	    cmd = LOCK_NB;
+	    break;
+	  default:
+	    cmd = 0;
+	    break;
+	  }
+	switch (fl->l_type)
+	  {
+	  case F_RDLCK: cmd |= LOCK_SH; break;
+	  case F_WRLCK: cmd |= LOCK_EX; break;
+	  case F_UNLCK: cmd |= LOCK_UN; break;
 	  default:
 	    errno = EINVAL;
 	    return -1;
 	  }
-      }
-
-    case F_GETLK64:
-    case F_SETLK64:
-    case F_SETLKW64:
-      {
-	struct flock64 *fl = va_arg (ap, struct flock64 *);
-	int wait = 0;
-	va_end (ap);
-	switch (cmd)
+	switch (fl->l_whence)
 	  {
-	  case F_GETLK64:
-	    errno = ENOSYS;
-	    return -1;
-	  case F_SETLKW64:
-	    wait = 1;
+	  case SEEK_SET:
+	    if (fl->l_start == 0 && fl->l_len == 0) /* Whole file request.  */
+	      break;
+	    /* It seems to be common for applications to lock the first
+	       byte of the file when they are really doing whole-file locking.
+	       So, since it's so wrong already, might as well do that too.  */
+	    if (fl->l_start == 0 && fl->l_len == 1)
+	      break;
 	    /* FALLTHROUGH */
-	  case F_SETLK64:
-	    return __f_setlk (fd, fl->l_type, fl->l_whence,
-			      fl->l_start, fl->l_len, wait);
+	  case SEEK_CUR:
+	  case SEEK_END:
+	    errno = ENOTSUP;
+	    return -1;
 	  default:
 	    errno = EINVAL;
 	    return -1;
 	  }
+
+	return __flock (fd, cmd);
       }
 
     case F_GETFL:		/* Get per-open flags.  */
@@ -208,4 +215,3 @@
 libc_hidden_def (__libc_fcntl64)
 weak_alias (__libc_fcntl64, __fcntl64)
 libc_hidden_weak (__fcntl64)
-weak_alias (__fcntl64, fcntl64)
--- a/sysdeps/mach/hurd/fcntl64.c	2019-01-31 17:45:36.000000000 +0100
+++ /dev/null	2017-01-20 12:59:50.000000000 +0100
@@ -1 +0,0 @@
-/* fcntl64 is defined in fcntl.c as an alias.  */
--- a/sysdeps/mach/hurd/f_setlk.c	2019-09-11 14:25:03.000000000 +0200
+++ b/sysdeps/mach/hurd/f_setlk.c	2019-09-11 14:29:12.000000000 +0200
@@ -1,5 +1,5 @@
 /* f_setlk -- locking part of fcntl
-   Copyright (C) 2014-2019 Free Software Foundation, Inc.
+   Copyright (C) 2014-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -19,7 +19,6 @@
 #include <sys/types.h>
 #include <sys/file.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <errno.h>
 
 /* XXX
@@ -46,18 +45,6 @@
   if (cmd != LOCK_UN && wait == 0)
     cmd |= LOCK_NB;
 
-  if (whence == SEEK_CUR)
-    {
-      /* In case the target position is 0, we can support it below.  */
-      __off64_t cur = __lseek64 (fd, 0, SEEK_CUR);
-
-      if (cur >= 0)
-	{
-	  start = cur + start;
-	  whence = SEEK_SET;
-	}
-    }
-
   switch (whence)
     {
     case SEEK_SET:

Reply via email to