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

[PATCH hurd 2/6] Add file record locking support



libdiskfs: implement diskfs_S_file_record_lock and modify diskfs_S_*
accordingly, initialize and release lock_status
libdiskfs/ChangeLog
2014-08-21  Svante Signell <svante.signell@gmail.com>

	* define temporary CPP_FLAGS until glibc is updated
	* file-lock-stat.c: Port from cthreads to libpthread.
	* file-lock.c: Likewise
	* file-record-lock: Likewise

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

	* Makefile (FSSRCS): Add file-record-lock.c.
	* diskfs.h (struct peropen): Change the type of lock_status
	from an int to a struct rlock_peropen.
	(struct node): Change the type of userbox from a struct lock_box
	to a struct rlock_box.
	* dir-lookup.c (diskfs_S_dir_lookup): Use fshelp_tweak_rlock
	as fshelp_acquire_lock is now depreciated.
	* file-lock-stat.c (diskfs_S_file_lock_stat): Total rewrite
	around the new record locking functions.
	* file-lock.c (diskfs_S_file_lock): Total rewrite around the
	new record locking functions.
	* file-record-lock.c: New file.  Implement
	diskfs_S_file_record_lock.
	* node-make.c (diskfs_make_node):  Initialize userbox with
	fshelp_rlock_init.
	* peropen-make.c (diskfs_make_peropen): Initialize lock_status
	using fshelp_rlock_po_init.
	* peropen-rele.c (diskfs_release_peropen): Release lock_status
	using fshelp_rlock_drop_peropen.
	
Index: hurd-0.5.git20141210/libdiskfs/Makefile
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/Makefile
+++ hurd-0.5.git20141210/libdiskfs/Makefile
@@ -26,7 +26,8 @@ FSSRCS= dir-chg.c dir-link.c dir-lookup.
 	file-get-trans.c file-get-transcntl.c file-getcontrol.c \
 	file-getfh.c file-getlinknode.c file-lock-stat.c \
 	file-lock.c file-set-size.c file-set-trans.c file-statfs.c \
-	file-sync.c file-syncfs.c file-utimes.c file-reparent.c
+	file-sync.c file-syncfs.c file-utimes.c file-record-lock.c \
+	file-reparent.c
 IOSRCS= io-async-icky.c io-async.c io-duplicate.c io-get-conch.c io-revoke.c \
 	io-map-cntl.c io-map.c io-modes-get.c io-modes-off.c \
 	io-modes-on.c io-modes-set.c io-owner-mod.c io-owner-get.c \
@@ -72,4 +73,10 @@ ifsock-MIGSFLAGS = -imacros $(srcdir)/fs
 exec_startup-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
 MIGCOMSFLAGS = -prefix diskfs_
 
+# Define the 64 bit versions of the second argument to fcntl()
+# Can safely be removed when glibc is updated
+EXTRA_CPP_FLAGS= -DF_GETLK64=10 -DF_SETLK64=11 -DF_SETLKW64=12
+dir-lookup-CPPFLAGS += $(EXTRA_CPP_FLAGS)
+file-lock-CPPFLAGS += $(EXTRA_CPP_FLAGS)
+
 include ../Makeconf
Index: hurd-0.5.git20141210/libdiskfs/diskfs.h
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/diskfs.h
+++ hurd-0.5.git20141210/libdiskfs/diskfs.h
@@ -56,8 +56,8 @@ struct protid
 /* One of these is created for each node opened by dir_lookup. */
 struct peropen
 {
-  off_t filepointer;
-  int lock_status;
+  loff_t filepointer;
+  struct rlock_peropen lock_status;
   refcount_t refcnt;
   int openstat;
 
@@ -105,7 +105,7 @@ struct node
 
   struct transbox transbox;
 
-  struct lock_box userlock;
+  struct rlock_box userlock;
 
   struct conch conch;
 
Index: hurd-0.5.git20141210/libdiskfs/dir-lookup.c
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/dir-lookup.c
+++ hurd-0.5.git20141210/libdiskfs/dir-lookup.c
@@ -517,12 +517,27 @@ diskfs_S_dir_lookup (struct protid *dirc
   if (! error)
     {
       newpo = 0;
+      struct flock64 lock =
+        {
+         l_start: 0,
+         l_len: 0,
+         l_whence: SEEK_SET
+       };
+
       if (flags & O_EXLOCK)
-	error = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status,
-				     &np->lock, LOCK_EX);
+        {
+         lock.l_type = F_WRLCK;
+         error = fshelp_rlock_tweak (&np->userlock, &np->lock,
+                                     &newpi->po->lock_status, flags, 0, 0,
+                                     F_SETLK64, &lock);
+       }
       else if (flags & O_SHLOCK)
-	error = fshelp_acquire_lock (&np->userlock, &newpi->po->lock_status,
-				     &np->lock, LOCK_SH);
+        {
+         lock.l_type = F_RDLCK;
+         error = fshelp_rlock_tweak (&np->userlock, &np->lock,
+                                     &newpi->po->lock_status, flags, 0, 0,
+                                     F_SETLK64, &lock);
+       }
     }
 
   if (! error)
Index: hurd-0.5.git20141210/libdiskfs/file-lock-stat.c
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/file-lock-stat.c
+++ hurd-0.5.git20141210/libdiskfs/file-lock-stat.c
@@ -1,38 +1,43 @@
-/*
-   Copyright (C) 1994, 1995 Free Software Foundation
+/* Copyright (C) 2001, 2014 Free Software Foundation, Inc.
 
-This file is part of the GNU Hurd.
+   Written by Neal H Walfield <neal@cs.uml.edu>
 
-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; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-/* Written by Michael I. Bushnell.  */
+   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 this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
 #include "fs_S.h"
 
+#include <fcntl.h>
+#include <sys/file.h>
+
 kern_return_t
 diskfs_S_file_lock_stat (struct protid *cred,
 			 int *mystatus,
 			 int *otherstatus)
 {
+  struct node *node;
+
   if (!cred)
     return EOPNOTSUPP;
-  
-  pthread_mutex_lock (&cred->po->np->lock);
-  *mystatus = cred->po->lock_status;
-  *otherstatus = cred->po->np->userlock.type;
-  pthread_mutex_unlock (&cred->po->np->lock);
+
+  node = cred->po->np;
+
+  pthread_mutex_lock (&node->lock);
+  *mystatus = fshelp_rlock_peropen_status (&cred->po->lock_status);
+  *otherstatus = fshelp_rlock_node_status (&node->userlock);
+  pthread_mutex_unlock (&node->lock);
+
   return 0;
 }
Index: hurd-0.5.git20141210/libdiskfs/file-lock.c
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/file-lock.c
+++ hurd-0.5.git20141210/libdiskfs/file-lock.c
@@ -1,36 +1,56 @@
-/*
-   Copyright (C) 1993, 1994 Free Software Foundation
+/* Copyright (C) 2001, 2014 Free Software Foundation, Inc.
 
-This file is part of the GNU Hurd.
+   Written by Neal H Walfield <neal@cs.uml.edu>
 
-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; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-/* Written by Michael I. Bushnell.  */
+   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 this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
 #include "fs_S.h"
 
+#include <fcntl.h>
+#include <sys/file.h>
+
 kern_return_t
 diskfs_S_file_lock (struct protid *cred, int flags)
 {
   error_t err;
-  if (!cred)
+  struct flock64 lock;
+  struct node *node;
+
+  if (! cred)
     return EOPNOTSUPP;
-  pthread_mutex_lock (&cred->po->np->lock);
-  err = fshelp_acquire_lock (&cred->po->np->userlock, &cred->po->lock_status,
-			     &cred->po->np->lock, flags);
-  pthread_mutex_unlock (&cred->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 = cred->po->np;
+  pthread_mutex_lock (&node->lock);
+  err = fshelp_rlock_tweak (&node->userlock, &node->lock,
+			    &cred->po->lock_status, cred->po->openstat,
+			    0, 0, flags & LOCK_NB ? F_SETLK64 : F_SETLKW64,
+			    &lock);
+  pthread_mutex_unlock (&node->lock);
   return err;
 }
Index: hurd-0.5.git20141210/libdiskfs/file-record-lock.c
===================================================================
--- /dev/null
+++ hurd-0.5.git20141210/libdiskfs/file-record-lock.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2001, 2014 Free Software Foundation, Inc.
+
+   Written by Neal H Walfield <neal@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 this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "priv.h"
+#include "diskfs.h"
+
+#include <errno.h>
+#include <hurd/fshelp.h>
+
+error_t
+diskfs_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->dn_stat.st_size, cred->po->filepointer,
+			    cmd, lock);
+  pthread_mutex_unlock (&node->lock);
+  return err;
+}
Index: hurd-0.5.git20141210/libdiskfs/node-make.c
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/node-make.c
+++ hurd-0.5.git20141210/libdiskfs/node-make.c
@@ -41,7 +41,7 @@ init_node (struct node *np, struct diskn
 
   fshelp_transbox_init (&np->transbox, &np->lock, np);
   iohelp_initialize_conch (&np->conch, &np->lock);
-  fshelp_lock_init (&np->userlock);
+  fshelp_rlock_init (&np->userlock);
 
   return np;
 }
Index: hurd-0.5.git20141210/libdiskfs/peropen-make.c
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/peropen-make.c
+++ hurd-0.5.git20141210/libdiskfs/peropen-make.c
@@ -16,7 +16,10 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include <errno.h>
+#include <stdlib.h>
 #include <sys/file.h>
+#include <hurd/fshelp.h>
 
 /* Create and return a new peropen structure on node NP with open
    flags FLAGS.  */
@@ -24,13 +27,17 @@ error_t
 diskfs_make_peropen (struct node *np, int flags, struct peropen *context,
 		     struct peropen **ppo)
 {
+  error_t err;
   struct peropen *po = *ppo = malloc (sizeof (struct peropen));
 
   if (! po)
     return ENOMEM;
 
+  err = fshelp_rlock_po_init (&po->lock_status);
+  if (err)
+    return err;
+
   po->filepointer = 0;
-  po->lock_status = LOCK_UN;
   refcount_init (&po->refcnt, 1);
   po->openstat = flags;
   po->np = np;
Index: hurd-0.5.git20141210/libdiskfs/peropen-rele.c
===================================================================
--- hurd-0.5.git20141210.orig/libdiskfs/peropen-rele.c
+++ hurd-0.5.git20141210/libdiskfs/peropen-rele.c
@@ -1,5 +1,5 @@
-/* 
-   Copyright (C) 1994, 1996, 1997 Free Software Foundation
+/*
+   Copyright (C) 1994, 1996, 1997, 2014 Free Software Foundation
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -33,16 +33,8 @@ diskfs_release_peropen (struct peropen *
 
   if (po->shadow_root_parent)
     mach_port_deallocate (mach_task_self (), po->shadow_root_parent);
-
-  if (po->lock_status != LOCK_UN)
-    {
-      pthread_mutex_lock (&po->np->lock);
-      fshelp_acquire_lock (&po->np->userlock, &po->lock_status,
-                           &po->np->lock, LOCK_UN);
-      diskfs_nput (po->np);
-    }
-  else
-    diskfs_nrele (po->np);
+  fshelp_rlock_drop_peropen (&po->lock_status);
+  diskfs_nput (po->np);
 
   free (po->path);
   free (po);

Reply to: