Note: Until all recent changes in libnetfs have settled: this patch relates to
the changes before Flavios patches starting with the refcount_t usage for
peropen references.

Implementation of libnetfs is added to the original patches.

Test cases: ftpfs and dh_gencontrol via fakeroot.

ftpfs (F_RDLCK):
settrans -c ftp: /hurd/hostmux /hurd/ftpfs /
cat ftp://ftp.gnu.org/README
./set-fcntl ftp://ftp.gnu.org/README O_READ F_SETLK F_RDLCK
<ok>

fakeroot (LOCK_EX/F_WRLCK):
dh_gencontrol -> dpkg-gencontrol -> /usr/share/perl5/Dpkg/File.pm
sub file_lock($$) {
    if ($@) {
        warning(g_('File::FcntlLock not available; using flock which is not NFS-
safe'));
        flock($fh, LOCK_EX)
            or syserr(g_('failed to get a write lock on %s'), $filename);
    } else {
        eval q{
            my $fs = File::FcntlLock->new(l_type => F_WRLCK);
            $fs->lock($fh, F_SETLKW)
                or syserr(g_('failed to get a write lock on %s'), $filename);
        }
    }
libnetfs/ChangeLog
2015-12-15  Svante Signell <svante.sign...@gmail.com>

	* netfs.h (struct peropen): Add a comment why refcount_t
	cannot be used for refcnt in struct peropen.
	(struct peropen): Change the type of refcnt from int to refcount_t
	(struct node): Change the type of userbox from a struct lock_box
	to a struct rlock_box.
	* dir-lookup.c (netfs_S_dir_lookup): Use fshelp_rlock_tweak.
	* file-lock-stat.c (netfs_S_file_lock_stat): Total rewrite
	around the new record locking functions.
	* file-lock.c (netfs_S_file_lock): Likewise.
	* file-record-lock.c (netfs_S_file_record_lock): Likewise.
	* make-node.c (netfs_make_node): Initialize userbox with
	fshelp_rlock_init.
	* make-peropen.c (netfs_make_peropen): Initialize lock_status
	using fshelp_rlock_po_init.
	(netfs_make_peropen): Add a comment that po->refcnt starts at zero.
	* relese-peropen.c (netfs_release_peropen): Release lock_status
	using fshelp_rlock_drop_peropen.
		
2001-04-11  Neal H Walfield  <n...@cs.uml.edu>

	* file-record-lock.c: New file.  Implement
	netfs_S_file_record_lock.
	* Makefile (SRCS): Add file-record-lock.c

Index: hurd-0.7.git20160114/libnetfs/Makefile
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/Makefile
+++ hurd-0.7.git20160114/libnetfs/Makefile
@@ -34,8 +34,8 @@ FSSRCS= dir-link.c dir-lookup.c dir-mkdi
 	file-get-translator.c file-getcontrol.c file-getlinknode.c \
 	file-lock-stat.c file-lock.c file-set-size.c \
 	file-set-translator.c file-statfs.c file-sync.c file-syncfs.c \
-	file-utimes.c file-reparent.c fsstubs.c	file-get-transcntl.c \
-	get-source.c
+	file-utimes.c file-record-lock.c file-reparent.c fsstubs.c \
+	file-get-transcntl.c get-source.c
 
 IOSRCS=	io-read.c io-readable.c io-seek.c io-write.c io-stat.c io-async.c     \
 	io-set-all-openmodes.c io-get-openmodes.c io-set-some-openmodes.c     \
@@ -70,7 +70,6 @@ io-MIGSFLAGS = -imacros $(srcdir)/mutati
 ifsock-MIGSFLAGS = -imacros $(srcdir)/mutations.h
 MIGCOMSFLAGS = -prefix netfs_
 
-
 include ../Makeconf
 
 fsysServer.c fsys_S.h fsServer.c fs_S.h ioServer.c io_S.h ifsockServer.c ifsock_S.h: mutations.h
Index: hurd-0.7.git20160114/libnetfs/netfs.h
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/netfs.h
+++ hurd-0.7.git20160114/libnetfs/netfs.h
@@ -24,6 +24,7 @@
 #include <hurd/iohelp.h>
 #include <assert.h>
 #include <pthread.h>
+#include <refcount.h>
 
 /* This library supports client-side network file system
    implementations.  It is analogous to the diskfs library provided for
@@ -50,7 +51,7 @@ struct protid
 struct peropen
 {
   loff_t filepointer;
-  int lock_status;
+  struct rlock_peropen lock_status;
   int refcnt;
   int openstat;
 
@@ -93,7 +94,7 @@ struct node
 
   struct transbox transbox;
 
-  struct lock_box userlock;
+  struct rlock_box userlock;
 
   struct conch conch;
 
Index: hurd-0.7.git20160114/libnetfs/dir-lookup.c
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/dir-lookup.c
+++ hurd-0.7.git20160114/libnetfs/dir-lookup.c
@@ -453,24 +453,49 @@ netfs_S_dir_lookup (struct protid *dirus
       goto out;
     }
 
-  free (newpi->po->path);
-  if (diruser->po->path == NULL || !strcmp (diruser->po->path,"."))
+  struct flock64 lock =
     {
-      /* diruser is the root directory.  */
-      newpi->po->path = relpath;
-      relpath = NULL; /* Do not free relpath.  */
+    l_start: 0,
+    l_len: 0,
+    l_whence: SEEK_SET
+    };
+
+  if (flags & O_EXLOCK)
+    {
+      lock.l_type = F_WRLCK;
+      error = fshelp_rlock_tweak (&np->userlock, &np->lock,
+				&newpi->po->lock_status, flags, 0, 0,
+				F_SETLK64, &lock);
     }
-  else
+  else if (flags & O_SHLOCK)
     {
-      newpi->po->path = NULL;
-      asprintf (&newpi->po->path, "%s/%s", diruser->po->path, relpath);
+      lock.l_type = F_RDLCK;
+      error = fshelp_rlock_tweak (&np->userlock, &np->lock,
+				&newpi->po->lock_status, flags, 0, 0,
+				F_SETLK64, &lock);
     }
 
-  if (! newpi->po->path)
-    error = errno;
+  if (! error)
+    {
+      free (newpi->po->path);
+      if (diruser->po->path == NULL || !strcmp (diruser->po->path,"."))
+	{
+	  /* diruser is the root directory.  */
+	  newpi->po->path = relpath;
+	  relpath = NULL; /* Do not free relpath.  */
+	}
+      else
+	{
+	  newpi->po->path = NULL;
+	  asprintf (&newpi->po->path, "%s/%s", diruser->po->path, relpath);
+	}
 
-  *retry_port = ports_get_right (newpi);
-  ports_port_deref (newpi);
+      if (! newpi->po->path)
+	error = errno;
+
+      *retry_port = ports_get_right (newpi);
+      ports_port_deref (newpi);
+    }
 
  out:
   if (np)
Index: hurd-0.7.git20160114/libnetfs/file-lock-stat.c
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/file-lock-stat.c
+++ hurd-0.7.git20160114/libnetfs/file-lock-stat.c
@@ -1,5 +1,5 @@
-/* 
-   Copyright (C) 1995 Free Software Foundation, Inc.
+/*
+   Copyright (C) 1995, 2015 Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -21,17 +21,25 @@
 #include "netfs.h"
 #include "fs_S.h"
 
+#include <fcntl.h>
+#include <sys/file.h>
+
 error_t
 netfs_S_file_lock_stat (struct protid *user,
 			int *mystatus,
 			int *otherstatus)
 {
+
+  struct node *node;
+
   if (!user)
     return EOPNOTSUPP;
-  
-  pthread_mutex_lock (&user->po->np->lock);
-  *mystatus = user->po->lock_status;
-  *otherstatus = user->po->np->userlock.type;
-  pthread_mutex_unlock (&user->po->np->lock);
+
+  node = user->po->np;
+  pthread_mutex_lock (&node->lock);
+  *mystatus = fshelp_rlock_peropen_status (&user->po->lock_status);
+  *otherstatus = fshelp_rlock_node_status (&node->userlock);
+  pthread_mutex_unlock (&node->lock);
+
   return 0;
 }
Index: hurd-0.7.git20160114/libnetfs/file-lock.c
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/file-lock.c
+++ hurd-0.7.git20160114/libnetfs/file-lock.c
@@ -1,5 +1,5 @@
 /* 
-   Copyright (C) 1995 Free Software Foundation, Inc.
+   Copyright (C) 1995, 2015 Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -21,16 +21,40 @@
 #include "netfs.h"
 #include "fs_S.h"
 
+#include <fcntl.h>
+#include <sys/file.h>
+
 error_t
 netfs_S_file_lock (struct protid *user,
 		   int flags)
 {
   error_t err;
+  struct flock64 lock;
+  struct node *node;
+
   if (!user)
     return EOPNOTSUPP;
-  pthread_mutex_lock (&user->po->np->lock);
-  err = fshelp_acquire_lock (&user->po->np->userlock, &user->po->lock_status,
-			     &user->po->np->lock, flags);
-  pthread_mutex_unlock (&user->po->np->lock);
+
+  lock.l_whence = SEEK_SET;
+  lock.l_start = 0;
+  lock.l_len = 0;
+
+  if (flags & LOCK_UN)
+    lock.l_type = F_UNLCK;
+  else if (flags & LOCK_SH)
+    lock.l_type = F_RDLCK;
+  else if (flags & LOCK_EX)
+    lock.l_type = F_WRLCK;
+  else
+    return EINVAL;
+
+  node = user->po->np;
+  pthread_mutex_lock (&node->lock);
+  err = fshelp_rlock_tweak (&node->userlock, &node->lock,
+                           &user->po->lock_status, user->po->openstat,
+                           0, 0, flags & LOCK_NB ? F_SETLK64 : F_SETLKW64,
+                           &lock);
+  pthread_mutex_unlock (&node->lock);
+
   return err;
 }
Index: hurd-0.7.git20160114/libnetfs/make-node.c
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/make-node.c
+++ hurd-0.7.git20160114/libnetfs/make-node.c
@@ -1,5 +1,5 @@
 /* 
-   Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 2000, 2015 Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -32,7 +32,7 @@ init_node (struct node *np, struct netno
   np->owner = 0;
 
   fshelp_transbox_init (&np->transbox, &np->lock, np);
-  fshelp_lock_init (&np->userlock);
+  fshelp_rlock_init (&np->userlock);
   
   return np;
 }
Index: hurd-0.7.git20160114/libnetfs/make-peropen.c
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/make-peropen.c
+++ hurd-0.7.git20160114/libnetfs/make-peropen.c
@@ -1,5 +1,5 @@
-/* 
-   Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+/*
+   Copyright (C) 1995, 1997, 2015 Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -19,18 +19,25 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include "netfs.h"
+#include <errno.h>
+#include <stdlib.h>
 #include <sys/file.h>
 
 struct peropen *
 netfs_make_peropen (struct node *np, int flags, struct peropen *context)
 {
+  error_t err;
   struct peropen *po = malloc (sizeof (struct peropen));
 
   if (!po)
     return NULL;
 
   po->filepointer = 0;
-  po->lock_status = LOCK_UN;
+  err = fshelp_rlock_po_init (&po->lock_status);
+  if (err)
+    return NULL;
+  /* XXX: refcount_init() cannot be used since reference counting
+     starts at 0 not 1 as for libdiskfs */
   po->refcnt = 0;
   po->openstat = flags;
   po->np = np;
Index: hurd-0.7.git20160114/libnetfs/release-peropen.c
===================================================================
--- hurd-0.7.git20160114.orig/libnetfs/release-peropen.c
+++ hurd-0.7.git20160114/libnetfs/release-peropen.c
@@ -1,5 +1,5 @@
 /* 
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2015 Free Software Foundation, Inc.
    Written by Michael I. Bushnell, p/BSG.
 
    This file is part of the GNU Hurd.
@@ -40,10 +40,7 @@ netfs_release_peropen (struct peropen *p
       if (po->shadow_root_parent)
 	mach_port_deallocate (mach_task_self (), po->shadow_root_parent);
 
-      if (po->lock_status != LOCK_UN)
-	fshelp_acquire_lock (&po->np->userlock, &po->lock_status,
-			     &po->np->lock, LOCK_UN);
-
+      fshelp_rlock_drop_peropen (&po->lock_status);
       netfs_nput (po->np);
 
       free (po->path);
Index: hurd-0.7.git20160114/libnetfs/file-record-lock.c
===================================================================
--- /dev/null
+++ hurd-0.7.git20160114/libnetfs/file-record-lock.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2001, 2014, 2015 Free Software Foundation, Inc.
+
+   Written by Neal H Walfield <n...@cs.uml.edu>
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd 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.
+
+   The GNU Hurd 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 "netfs.h"
+#include "fs_S.h"
+
+#include <hurd/fshelp.h>
+
+error_t
+netfs_S_file_record_lock (struct protid *cred,
+			  int cmd,
+			  struct flock64 *lock)
+{
+  struct node *node;
+  error_t err;
+
+  if (! cred)
+    return EOPNOTSUPP;
+
+  node = cred->po->np;
+  pthread_mutex_lock (&node->lock);
+  err = fshelp_rlock_tweak (&node->userlock, &node->lock,
+			    &cred->po->lock_status, cred->po->openstat,
+			    node->nn_stat.st_size, cred->po->filepointer,
+			    cmd, lock);
+  pthread_mutex_unlock (&node->lock);
+  return err;
+}

Reply via email to