libnetfs/ChangeLog 2015-12-15 Svante Signell * 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 * 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 #include #include +#include /* 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 +#include + 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 +#include + 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 +#include #include 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 + + 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 . */ + +#include "netfs.h" +#include "fs_S.h" + +#include + +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; +}