summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/patches/ext2fs-fix-remount.patch679
-rw-r--r--debian/patches/series1
2 files changed, 0 insertions, 680 deletions
diff --git a/debian/patches/ext2fs-fix-remount.patch b/debian/patches/ext2fs-fix-remount.patch
deleted file mode 100644
index 120d8ae3..00000000
--- a/debian/patches/ext2fs-fix-remount.patch
+++ /dev/null
@@ -1,679 +0,0 @@
-Return-Path: <bug-hurd-bounces+4winter=informatik.uni-hamburg.de@gnu.org>
-X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on jade.jade-hamburg.de
-X-Spam-Level:
-X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,
- TVD_RCVD_SPACE_BRACKET,T_DKIM_INVALID,UNPARSEABLE_RELAY,URIBL_BLOCKED
- autolearn=ham version=3.3.1
-Received: from mailhost.informatik.uni-hamburg.de [134.100.9.70]
- by jade.jade-hamburg.de with IMAP (fetchmail-6.3.9-rc2)
- for <teythoon@localhost> (single-drop); Thu, 23 Jul 2015 19:35:41 +0200 (CEST)
-Received: from mailhost.informatik.uni-hamburg.de ([unix socket])
- by mailhost (Cyrus v2.3.18) with LMTPA;
- Thu, 23 Jul 2015 19:34:57 +0200
-X-Sieve: CMU Sieve 2.3
-Received: by mailhost.informatik.uni-hamburg.de (Postfix)
- id 25BA94D; Thu, 23 Jul 2015 19:34:57 +0200 (CEST)
-Delivered-To: 4winter@informatik.uni-hamburg.de
-Received: from localhost (localhost [127.0.0.1])
- by mailhost.informatik.uni-hamburg.de (Postfix) with ESMTP id 1B35E4C
- for <4winter@informatik.uni-hamburg.de>; Thu, 23 Jul 2015 19:34:57 +0200 (CEST)
-X-Virus-Scanned: amavisd-new at informatik.uni-hamburg.de
-Received: from mailhost.informatik.uni-hamburg.de ([127.0.0.1])
- by localhost (mailhost.informatik.uni-hamburg.de [127.0.0.1]) (amavisd-new, port 10024)
- with LMTP id VLxwzMHbQTir for <4winter@informatik.uni-hamburg.de>;
- Thu, 23 Jul 2015 19:34:47 +0200 (CEST)
-Received: from lists.gnu.org (lists.gnu.org [208.118.235.17])
- (using TLSv1 with cipher AES256-SHA (256/256 bits))
- (Client did not present a certificate)
- by mailhost.informatik.uni-hamburg.de (Postfix) with ESMTPS id 2594F49
- for <4winter@informatik.uni-hamburg.de>; Thu, 23 Jul 2015 19:34:46 +0200 (CEST)
-Received: from eggs.gnu.org ([2001:4830:134:3::10]:40942)
- by lists.gnu.org with esmtp (Exim 4.71)
- (envelope-from <jrtc27@jrtc27.com>) id 1ZIKO4-0007qU-QR
- for bug-hurd@gnu.org; Thu, 23 Jul 2015 13:34:31 -0400
-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
- (envelope-from <jrtc27@jrtc27.com>) id 1ZIKO0-0002Hh-GH
- for bug-hurd@gnu.org; Thu, 23 Jul 2015 13:34:28 -0400
-Received: from mail-wi0-x232.google.com ([2a00:1450:400c:c05::232]:37033)
- by eggs.gnu.org with esmtp (Exim 4.71)
- (envelope-from <jrtc27@jrtc27.com>) id 1ZIKNz-0002Gs-Oc
- for bug-hurd@gnu.org; Thu, 23 Jul 2015 13:34:24 -0400
-Received: by wibud3 with SMTP id ud3so3837098wib.0
- for <bug-hurd@gnu.org>; Thu, 23 Jul 2015 10:34:22 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jrtc27.com; s=google;
- h=from:to:cc:subject:date:message-id;
- bh=MZx4v6IKvYqW2p9EGv4bjIw37GP1x3TFNJaYlejzfE0=;
- b=hkiuwxdVQ68sVd6CkTch33kqkgnZ9s4CH7SZzY38ggPING7qgOCDBCue6guf4GF2We
- ff42ryixXeN4PfOBGuWFQV4wjPxHUvadTqU3AcVvOqbzpGaCnsoLyqbXF6XtTcEmLtGk
- q54TByl6OjRYhlBc0l4pqkPZrMJdMwyLQLXZA=
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20130820;
- h=x-gm-message-state:from:to:cc:subject:date:message-id;
- bh=MZx4v6IKvYqW2p9EGv4bjIw37GP1x3TFNJaYlejzfE0=;
- b=AGdApX6eRz/QjNXK/ayMLnE5fEP7sx450w2wQNw62XwbVOtmCbTnSuZ66PhQ7ZVBym
- mVQk0f4HpgYXWcdXGgX8+lUScJPqhM+jgktgVaRtgNCVgMf4zcbrZJdc/xRb/4UgTAHy
- 6A5v+Z3RwqrY5cqcRzDdVafP/zD1qE824WYd7fVM0Xkmeozr5rogNfEY6ug46n2THq1v
- hfC9WA/CRUBoAwK3Ul7+6bj7BdXAlhIl6UWDGUebfMN7ov471mJfgEDmeh5blC8WNU5/
- dxdZ2zNPE47wHS1xkfjhXMKO7GJNgvaLUb2/jkTSV0i6b/gsGI2qzBtCXeoV7pqmhXzi
- 3TTg==
-X-Gm-Message-State: ALoCoQkhcH2D4+79mwdeHYjrBQLxsFBIYEmUR02QpaOfkNGg5bNh4sTRLCMAG2jwoxx8+W/WfW62
-X-Received: by 10.194.58.69 with SMTP id o5mr18159012wjq.22.1437672861959;
- Thu, 23 Jul 2015 10:34:21 -0700 (PDT)
-From: James Clarke <jrtc27@jrtc27.com>
-To: bug-hurd@gnu.org
-Subject: [PATCH v3] Fix race condition in ext2fs when remounting
-Date: Thu, 23 Jul 2015 18:33:42 +0100
-Message-Id: <1437672822-99155-1-git-send-email-jrtc27@jrtc27.com>
-X-Mailer: git-send-email 2.4.6
-X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address
- (bad octet value).
-X-Received-From: 2a00:1450:400c:c05::232
-Cc: James Clarke <jrtc27@jrtc27.com>
-X-BeenThere: bug-hurd@gnu.org
-X-Mailman-Version: 2.1.14
-Precedence: list
-List-Id: Bug reports for the GNU Hurd <bug-hurd.gnu.org>
-List-Unsubscribe: <https://lists.gnu.org/mailman/options/bug-hurd>,
- <mailto:bug-hurd-request@gnu.org?subject=unsubscribe>
-List-Archive: <http://lists.gnu.org/archive/html/bug-hurd>
-List-Post: <mailto:bug-hurd@gnu.org>
-List-Help: <mailto:bug-hurd-request@gnu.org?subject=help>
-List-Subscribe: <https://lists.gnu.org/mailman/listinfo/bug-hurd>,
- <mailto:bug-hurd-request@gnu.org?subject=subscribe>
-Errors-To: bug-hurd-bounces+4winter=informatik.uni-hamburg.de@gnu.org
-Sender: bug-hurd-bounces+4winter=informatik.uni-hamburg.de@gnu.org
-
-On some systems, ext2fs.static would regularly hang at startup, as a
-race condition meant it would process paging requests while remounting.
-To fix this, libpager has been altered to allow inhibiting and resuming
-its worker threads, and ext2fs uses this to inhibit paging while
-remounting.
-
-* console/pager.c (pager_requests): New variable.
-(user_pager_init): Updated call to pager_start_workers to use new
-pager_requests variable.
-* daemons/runsystem.sh: Removed artificial delay working around the race
-condition.
-* ext2fs/ext2fs.c (diskfs_reload_global_state): Call new
-inhibit_ext2_pager and resume_ext2_pager functions, and leave sblock as
-non-NULL so it will be munmapped.
-* ext2fs/ext2fs.h (inhibit_ext2_pager,resume_ext2_pager): New functions.
-* ext2fs/pager.c (file_pager_requests): New variable.
-(create_disk_pager): Updated call to pager_start_workers to use new
-file_pager_requests variable.
-(inhibit_ext2_pager,resume_ext2_pager): New functions.
-* fatfs/fatfs.h (inhibit_fat_pager,resume_fat_pager): New functions.
-* fatfs/pager.c (file_pager_requests): New variable.
-(create_fat_pager): Updated call to pager_start_workers to use new
-file_pager_requests variable.
-(inhibit_fat_pager,resume_fat_pager): New functions.
-* libdiskfs/disk-pager.c (diskfs_disk_pager_requests): New variable.
-(diskfs_start_disk_pager): Updated call to pager_start_workers to use
-new diskfs_disk_pager_requests variable.
-* libdiskfs/diskfs-pager.h (diskfs_disk_pager_requests): New variable.
-* libpager/demuxer.c (struct pager_requests): Renamed struct requests to
-struct pager_requests. Replaced queue with queue_in and queue_out
-pointers. Added inhibit_wakeup field.
-(pager_demuxer): Updated to use new queue_in/queue_out pointers. Only
-wake up workers if not inhibited.
-(worker_func): Updated to use new queue_in/queue_out pointers. Final
-worker thread to sleep notifies the inhibit_wakeup condition variable.
-(pager_start_workers): Added out parameter for the requests instance.
-Allocate heap space shared by both queues. Initialise new inhibit_wakeup
-condition.
-(pager_inhibit_workers,pager_resume_workers): New functions.
-* libpager/pager.h (struct pager_requests): Public forward definition.
-(pager_start_workers): Added out parameter for the requests instance.
-(pager_inhibit_workers,pager_resume_workers): New functions.
-* libpager/queue.h (queue_empty): New function.
-* storeio/pager.c (pager_requests): New variable.
-(init_dev_paging): Updated call to pager_start_workers to use new
-pager_requests variable.
----
- console/pager.c | 3 +-
- daemons/runsystem.sh | 3 --
- ext2fs/ext2fs.c | 12 ++++-
- ext2fs/ext2fs.h | 6 +++
- ext2fs/pager.c | 33 ++++++++++++-
- fatfs/fatfs.h | 2 +
- fatfs/pager.c | 33 ++++++++++++-
- libdiskfs/disk-pager.c | 3 +-
- libdiskfs/diskfs-pager.h | 1 +
- libpager/demuxer.c | 119 ++++++++++++++++++++++++++++++++++++++++-------
- libpager/pager.h | 28 ++++++++++-
- libpager/queue.h | 8 ++++
- storeio/pager.c | 3 +-
- 13 files changed, 227 insertions(+), 27 deletions(-)
-
-diff --git a/console/pager.c b/console/pager.c
-index 5e13ba4..818e49d 100644
---- a/console/pager.c
-+++ b/console/pager.c
-@@ -42,6 +42,7 @@ struct user_pager_info
-
- /* We need a separate bucket for the pager ports. */
- static struct port_bucket *pager_bucket;
-+static struct pager_requests *pager_requests;
-
-
- /* Implement the pager_clear_user_data callback from the pager library. */
-@@ -133,7 +134,7 @@ user_pager_init (void)
- error (5, errno, "Cannot create pager bucket");
-
- /* Start libpagers worker threads. */
-- err = pager_start_workers (pager_bucket);
-+ err = pager_start_workers (pager_bucket, &pager_requests);
- if (err)
- error (5, err, "Cannot start pager worker threads");
- }
-diff --git a/daemons/runsystem.sh b/daemons/runsystem.sh
-index ae25a7d..5d0ad01 100644
---- a/daemons/runsystem.sh
-+++ b/daemons/runsystem.sh
-@@ -118,9 +118,6 @@ esac
- /hurd/mach-defpager
-
- # This is necessary to make stat / return the correct device ids.
--# Work around a race condition (probably in the root translator).
--for i in `seq 1 100000` ; do : ; done # XXX
--
- fsysopts / --update --readonly
-
- # Finally, start the actual init.
-diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c
-index d0fdfe7..03c9eed 100644
---- a/ext2fs/ext2fs.c
-+++ b/ext2fs/ext2fs.c
-@@ -207,10 +207,20 @@ main (int argc, char **argv)
- error_t
- diskfs_reload_global_state ()
- {
-+ error_t err;
-+
- pokel_flush (&global_pokel);
- pager_flush (diskfs_disk_pager, 1);
-- sblock = NULL;
-+
-+ /* libdiskfs is not responsible for inhibiting paging. */
-+ err = inhibit_ext2_pager ();
-+ if (err)
-+ return err;
-+
- get_hypermetadata ();
- map_hypermetadata ();
-+
-+ resume_ext2_pager ();
-+
- return 0;
- }
-diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
-index 96d8e9d..a744685 100644
---- a/ext2fs/ext2fs.h
-+++ b/ext2fs/ext2fs.h
-@@ -201,6 +201,12 @@ struct user_pager_info
- /* Set up the disk pager. */
- void create_disk_pager (void);
-
-+/* Inhibit the disk pager. */
-+error_t inhibit_ext2_pager (void);
-+
-+/* Resume the disk pager. */
-+void resume_ext2_pager (void);
-+
- /* Call this when we should turn off caching so that unused memory object
- ports get freed. */
- void drop_pager_softrefs (struct node *node);
-diff --git a/ext2fs/pager.c b/ext2fs/pager.c
-index b56c923..3e080f8 100644
---- a/ext2fs/pager.c
-+++ b/ext2fs/pager.c
-@@ -34,6 +34,10 @@ struct port_bucket *disk_pager_bucket;
- /* A ports bucket to hold file pager ports. */
- struct port_bucket *file_pager_bucket;
-
-+/* Stores a reference to the requests instance used by the file pager so its
-+ worker threads can be inhibited and resumed. */
-+struct pager_requests *file_pager_requests;
-+
- pthread_spinlock_t node_to_page_lock = PTHREAD_SPINLOCK_INITIALIZER;
-
-
-@@ -1217,11 +1221,38 @@ create_disk_pager (void)
- file_pager_bucket = ports_create_bucket ();
-
- /* Start libpagers worker threads. */
-- err = pager_start_workers (file_pager_bucket);
-+ err = pager_start_workers (file_pager_bucket, &file_pager_requests);
- if (err)
- ext2_panic ("can't create libpager worker threads: %s", strerror (err));
- }
-
-+error_t
-+inhibit_ext2_pager (void)
-+{
-+ error_t err;
-+
-+ /* The file pager can rely on the disk pager, so inhibit the file
-+ pager first. */
-+
-+ err = pager_inhibit_workers (file_pager_requests);
-+ if (err)
-+ return err;
-+
-+ err = pager_inhibit_workers (diskfs_disk_pager_requests);
-+ /* We don't want only one pager disabled. */
-+ if (err)
-+ pager_resume_workers (file_pager_requests);
-+
-+ return err;
-+}
-+
-+void
-+resume_ext2_pager (void)
-+{
-+ pager_resume_workers (diskfs_disk_pager_requests);
-+ pager_resume_workers (file_pager_requests);
-+}
-+
- /* Call this to create a FILE_DATA pager and return a send right.
- NODE must be locked. */
- mach_port_t
-diff --git a/fatfs/fatfs.h b/fatfs/fatfs.h
-index 3c3d836..54c3426 100644
---- a/fatfs/fatfs.h
-+++ b/fatfs/fatfs.h
-@@ -121,6 +121,8 @@ extern struct dirrect dr_root_node;
- void drop_pager_softrefs (struct node *);
- void allow_pager_softrefs (struct node *);
- void create_fat_pager (void);
-+error_t inhibit_fat_pager (void);
-+void resume_fat_pager (void);
-
- void flush_node_pager (struct node *node);
-
-diff --git a/fatfs/pager.c b/fatfs/pager.c
-index 10d1fc9..d255f29 100644
---- a/fatfs/pager.c
-+++ b/fatfs/pager.c
-@@ -29,6 +29,10 @@ struct port_bucket *disk_pager_bucket;
- /* A ports bucket to hold file pager ports. */
- struct port_bucket *file_pager_bucket;
-
-+/* Stores a reference to the requests instance used by the file pager so its
-+ worker threads can be inhibited and resumed. */
-+struct pager_requests *file_pager_requests;
-+
- /* Mapped image of the FAT. */
- void *fat_image;
-
-@@ -776,11 +780,38 @@ create_fat_pager (void)
- file_pager_bucket = ports_create_bucket ();
-
- /* Start libpagers worker threads. */
-- err = pager_start_workers (file_pager_bucket);
-+ err = pager_start_workers (file_pager_bucket, &file_pager_requests);
- if (err)
- error (2, err, "can't create libpager worker threads");
- }
-
-+error_t
-+inhibit_fat_pager (void)
-+{
-+ error_t err;
-+
-+ /* The file pager can rely on the disk pager, so inhibit the file
-+ pager first. */
-+
-+ err = pager_inhibit_workers (file_pager_requests);
-+ if (err)
-+ return err;
-+
-+ err = pager_inhibit_workers (diskfs_disk_pager_requests);
-+ /* We don't want only one pager disabled. */
-+ if (err)
-+ pager_resume_workers (file_pager_requests);
-+
-+ return err;
-+}
-+
-+void
-+resume_fat_pager (void)
-+{
-+ pager_resume_workers (diskfs_disk_pager_requests);
-+ pager_resume_workers (file_pager_requests);
-+}
-+
- /* Call this to create a FILE_DATA pager and return a send right.
- NODE must be locked. */
- mach_port_t
-diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
-index 008aa2d..33b109c 100644
---- a/libdiskfs/disk-pager.c
-+++ b/libdiskfs/disk-pager.c
-@@ -24,6 +24,7 @@
- __thread struct disk_image_user *diskfs_exception_diu;
-
- struct pager *diskfs_disk_pager;
-+struct requests *diskfs_disk_pager_requests;
-
- static void fault_handler (int sig, long int sigcode, struct sigcontext *scp);
- static struct hurd_signal_preemptor preemptor =
-@@ -43,7 +44,7 @@ diskfs_start_disk_pager (struct user_pager_info *upi,
- mach_port_t disk_pager_port;
-
- /* Start libpagers worker threads. */
-- err = pager_start_workers (pager_bucket);
-+ err = pager_start_workers (pager_bucket, &diskfs_disk_pager_requests);
- if (err)
- error (2, err, "creating pager worker threads failed");
-
-diff --git a/libdiskfs/diskfs-pager.h b/libdiskfs/diskfs-pager.h
-index a253069..db99f9ff 100644
---- a/libdiskfs/diskfs-pager.h
-+++ b/libdiskfs/diskfs-pager.h
-@@ -40,6 +40,7 @@ extern void diskfs_start_disk_pager (struct user_pager_info *info,
- size_t size, void **image);
-
- extern struct pager *diskfs_disk_pager;
-+extern struct requests *diskfs_disk_pager_requests;
-
- struct disk_image_user
- {
-diff --git a/libpager/demuxer.c b/libpager/demuxer.c
-index 4dd3cd8..59dd1c5 100644
---- a/libpager/demuxer.c
-+++ b/libpager/demuxer.c
-@@ -60,7 +60,7 @@ request_inp (const struct request *r)
- /* A worker. */
- struct worker
- {
-- struct requests *requests; /* our pagers request queue */
-+ struct pager_requests *requests; /* our pagers request queue */
- struct queue queue; /* other workers may delegate requests to us */
- unsigned long tag; /* tag of the object we are working on */
- };
-@@ -68,12 +68,18 @@ struct worker
- /* This is the queue for incoming requests. A single thread receives
- messages from the port set, looks the service routine up, and
- enqueues the request here. */
--struct requests
-+struct pager_requests
- {
- struct port_bucket *bucket;
-- struct queue queue;
-+ /* Normally, both queues are the same. However, when the workers are
-+ inhibited, a new queue_in is created, but queue_out is left as the
-+ old value, so the workers drain queue_out but do not receive new
-+ requests. */
-+ struct queue *queue_in; /* the queue to add to */
-+ struct queue *queue_out; /* the queue to take from */
- int asleep;
- pthread_cond_t wakeup;
-+ pthread_cond_t inhibit_wakeup;
- pthread_mutex_t lock;
- struct worker workers[WORKER_COUNT];
- };
-@@ -81,7 +87,7 @@ struct requests
- /* Demultiplex a single message directed at a pager port; INP is the
- message received; fill OUTP with the reply. */
- static int
--pager_demuxer (struct requests *requests,
-+pager_demuxer (struct pager_requests *requests,
- mach_msg_header_t *inp,
- mach_msg_header_t *outp)
- {
-@@ -108,10 +114,10 @@ pager_demuxer (struct requests *requests,
-
- pthread_mutex_lock (&requests->lock);
-
-- queue_enqueue (&requests->queue, &r->item);
-+ queue_enqueue (requests->queue_in, &r->item);
-
-- /* Awake worker. */
-- if (requests->asleep > 0)
-+ /* Awake worker, but only if not inhibited. */
-+ if (requests->asleep > 0 && requests->queue_in == requests->queue_out)
- pthread_cond_signal (&requests->wakeup);
-
- pthread_mutex_unlock (&requests->lock);
-@@ -160,7 +166,7 @@ static void *
- worker_func (void *arg)
- {
- struct worker *self = (struct worker *) arg;
-- struct requests *requests = self->requests;
-+ struct pager_requests *requests = self->requests;
- struct request *r = NULL;
- mig_reply_header_t reply_msg;
-
-@@ -186,9 +192,11 @@ worker_func (void *arg)
-
- get_request_locked:
- /* ... get a request from the global queue instead. */
-- while ((r = queue_dequeue (&requests->queue)) == NULL)
-+ while ((r = queue_dequeue (requests->queue_out)) == NULL)
- {
- requests->asleep += 1;
-+ if (requests->asleep == WORKER_COUNT)
-+ pthread_cond_broadcast (&requests->inhibit_wakeup);
- pthread_cond_wait (&requests->wakeup, &requests->lock);
- requests->asleep -= 1;
- }
-@@ -281,7 +289,7 @@ worker_func (void *arg)
- static void *
- service_paging_requests (void *arg)
- {
-- struct requests *requests = arg;
-+ struct pager_requests *requests = arg;
-
- int demuxer (mach_msg_header_t *inp,
- mach_msg_header_t *outp)
-@@ -298,27 +306,44 @@ service_paging_requests (void *arg)
-
- /* Start the worker threads libpager uses to service requests. */
- error_t
--pager_start_workers (struct port_bucket *pager_bucket)
-+pager_start_workers (struct port_bucket *pager_bucket,
-+ struct pager_requests **out_requests)
- {
- error_t err;
- int i;
- pthread_t t;
-- struct requests *requests;
-+ struct pager_requests *requests;
-+
-+ assert (out_requests != NULL);
-
- requests = malloc (sizeof *requests);
- if (requests == NULL)
-- return ENOMEM;
-+ {
-+ err = ENOMEM;
-+ goto done;
-+ }
-
- requests->bucket = pager_bucket;
- requests->asleep = 0;
-- queue_init (&requests->queue);
-+
-+ requests->queue_in = malloc (sizeof *requests->queue_in);
-+ if (requests->queue_in == NULL)
-+ {
-+ err = ENOMEM;
-+ goto done;
-+ }
-+ queue_init (requests->queue_in);
-+ /* Until the workers are inhibited, both queues are the same. */
-+ requests->queue_out = requests->queue_in;
-+
- pthread_cond_init (&requests->wakeup, NULL);
-+ pthread_cond_init (&requests->inhibit_wakeup, NULL);
- pthread_mutex_init (&requests->lock, NULL);
-
- /* Make a thread to service paging requests. */
- err = pthread_create (&t, NULL, service_paging_requests, requests);
- if (err)
-- return err;
-+ goto done;
- pthread_detach (t);
-
- for (i = 0; i < WORKER_COUNT; i++)
-@@ -329,9 +354,71 @@ pager_start_workers (struct port_bucket *pager_bucket)
-
- err = pthread_create (&t, NULL, &worker_func, &requests->workers[i]);
- if (err)
-- return err;
-+ goto done;
- pthread_detach (t);
- }
-
-+done:
-+ if (err)
-+ *out_requests = NULL;
-+ else
-+ *out_requests = requests;
-+
- return err;
- }
-+
-+error_t
-+pager_inhibit_workers (struct pager_requests *requests)
-+{
-+ error_t err = 0;
-+
-+ pthread_mutex_lock (&requests->lock);
-+
-+ /* Check the workers are not already inhibited. */
-+ assert (requests->queue_out == requests->queue_in);
-+
-+ /* Any new paging requests will go into a new queue. */
-+ struct queue *new_queue = malloc (sizeof *new_queue);
-+ if (new_queue == NULL)
-+ {
-+ err = ENOMEM;
-+ goto done_locked;
-+ }
-+ queue_init (new_queue);
-+ requests->queue_in = new_queue;
-+
-+ /* Wait until all the workers are asleep and the queue has been
-+ drained. All individual worker queues must have been drained, as
-+ they are populated while the relevant worker is still running, and
-+ it will always drain its personal queue before sleeping.
-+ Check that the queue is empty, since it's possible that a request
-+ came in, was queued and a worker was signalled but the lock was
-+ acquired here before the worker woke up. */
-+ while (requests->asleep < WORKER_COUNT || !queue_empty(requests->queue_out))
-+ pthread_cond_wait (&requests->inhibit_wakeup, &requests->lock);
-+
-+done_locked:
-+ pthread_mutex_unlock (&requests->lock);
-+ return err;
-+}
-+
-+void
-+pager_resume_workers (struct pager_requests *requests)
-+{
-+ pthread_mutex_lock (&requests->lock);
-+
-+ /* Check the workers are inhibited. */
-+ assert (requests->queue_out != requests->queue_in);
-+ assert (requests->asleep == WORKER_COUNT);
-+ assert (queue_empty(requests->queue_out));
-+
-+ /* The queue has been drained and will no longer be used. */
-+ free (requests->queue_out);
-+ requests->queue_out = requests->queue_in;
-+
-+ /* We need to wake up all workers, as there could be multiple requests
-+ in the new queue. */
-+ pthread_cond_broadcast (&requests->wakeup);
-+
-+ pthread_mutex_unlock (&requests->lock);
-+}
-diff --git a/libpager/pager.h b/libpager/pager.h
-index fe34238..df4db68 100644
---- a/libpager/pager.h
-+++ b/libpager/pager.h
-@@ -25,8 +25,32 @@
- scope. */
- struct user_pager_info;
-
--/* Start the worker threads libpager uses to service requests. */
--error_t pager_start_workers (struct port_bucket *pager_bucket);
-+struct pager_requests;
-+
-+/* Start the worker threads libpager uses to service requests. If no
-+ error is returned, *requests will be a valid pointer, else it will be
-+ set to NULL. */
-+error_t
-+pager_start_workers (struct port_bucket *pager_bucket,
-+ struct pager_requests **requests);
-+
-+/* Inhibit the worker threads libpager uses to service requests,
-+ blocking until all requests sent before this function is called have
-+ finished.
-+ Note that RPCs will not be inhibited, so new requests will
-+ queue up, but will not be handled until the workers are resumed. If
-+ RPCs should be inhibited as well, call ports_inhibit_bucket_rpcs with
-+ the bucket used to create the workers before calling this. However,
-+ inhibiting RPCs and not calling this is generally insufficient, as
-+ libports is unaware of our internal worker pool, and will return once
-+ all the RPCs have been queued, before they have been handled by a
-+ worker thread. */
-+error_t
-+pager_inhibit_workers (struct pager_requests *requests);
-+
-+/* Resume the worker threads libpager uses to service requests. */
-+void
-+pager_resume_workers (struct pager_requests *requests);
-
- /* Create a new pager. The pager will have a port created for it
- (using libports, in BUCKET) and will be immediately ready
-diff --git a/libpager/queue.h b/libpager/queue.h
-index d3cf738..abcd3b9 100644
---- a/libpager/queue.h
-+++ b/libpager/queue.h
-@@ -19,6 +19,8 @@
- 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 <stdbool.h>
-+
- /* A FIFO queue with constant-time enqueue and dequeue operations. */
- struct item {
- struct item *next;
-@@ -59,3 +61,9 @@ queue_dequeue (struct queue *q)
- r->next = NULL;
- return r;
- }
-+
-+static inline bool
-+queue_empty (struct queue *q)
-+{
-+ return q->head == NULL;
-+}
-diff --git a/storeio/pager.c b/storeio/pager.c
-index c260d73..f8f59cd 100644
---- a/storeio/pager.c
-+++ b/storeio/pager.c
-@@ -142,6 +142,7 @@ pager_clear_user_data (struct user_pager_info *upi)
- }
-
- static struct port_bucket *pager_port_bucket = 0;
-+static struct pager_requests *pager_requests;
-
- /* Initialize paging for this device. */
- static void
-@@ -160,7 +161,7 @@ init_dev_paging ()
- pager_port_bucket = ports_create_bucket ();
-
- /* Start libpagers worker threads. */
-- err = pager_start_workers (pager_port_bucket);
-+ err = pager_start_workers (pager_port_bucket, &pager_requests);
- if (err)
- {
- errno = err;
---
-2.4.6
-
-
diff --git a/debian/patches/series b/debian/patches/series
index 7a9a374d..ec7305a7 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,5 +1,4 @@
mach-defpager-dl.patch
-ext2fs-fix-remount.patch
libexec.patch
diskfs_no_inherit_dir_group.patch