summaryrefslogtreecommitdiff
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/exec_filename_exec.patch23
-rw-r--r--debian/patches/exec_filename_fs.patch6
-rw-r--r--debian/patches/ext2fs_large_stores.patch2274
-rw-r--r--debian/patches/ext2fs_large_stores_pthread.patch344
-rw-r--r--debian/patches/mount-f.patch88
-rw-r--r--debian/patches/mount-ignore-mounted-all.patch32
-rw-r--r--debian/patches/mount-n.patch37
-rw-r--r--debian/patches/mount-remount.patch67
-rw-r--r--debian/patches/mount-t-auto.patch86
-rw-r--r--debian/patches/mount-test-opts.patch209
-rw-r--r--debian/patches/procfs-default.patch48
-rw-r--r--debian/patches/procfs-get-options.patch73
-rw-r--r--debian/patches/procfs-update.patch143
-rw-r--r--debian/patches/proxy-defpager.diff4
-rw-r--r--debian/patches/series16
-rw-r--r--debian/patches/sutils-multiple-none.patch40
-rw-r--r--debian/patches/sutils-types.patch150
-rw-r--r--debian/patches/umount.patch382
18 files changed, 16 insertions, 4006 deletions
diff --git a/debian/patches/exec_filename_exec.patch b/debian/patches/exec_filename_exec.patch
index 41b66a82..1e937b45 100644
--- a/debian/patches/exec_filename_exec.patch
+++ b/debian/patches/exec_filename_exec.patch
@@ -134,15 +134,6 @@ Index: hurd-debian/exec/exec.c
if (! protid)
return EOPNOTSUPP;
-@@ -2111,7 +2151,7 @@
- trivfs_protid_portclasses[0]);
- if (protid)
- {
-- err = do_exec (file, oldtask, 0,
-+ err = do_exec (file, oldtask, 0, filename,
- argv, argvlen, argv_copy,
- envp, envplen, envp_copy,
- dtable, dtablesize, dtable_copy,
@@ -2158,7 +2198,7 @@
/* There were no user-specified exec servers,
or none of them could be found. */
@@ -304,14 +295,14 @@ Index: hurd-debian/exec/Makefile
--- hurd-debian.orig/exec/Makefile 2012-06-03 17:08:36.000000000 +0000
+++ hurd-debian/exec/Makefile 2012-06-05 03:39:06.000000000 +0000
@@ -23,7 +23,7 @@
- SRCS = exec.c main.c hashexec.c hostarch.c \
- $(gzip-sources) $(bzip2-sources)
+
+ SRCS = exec.c main.c hashexec.c hostarch.c
OBJS = main.o hostarch.o exec.o hashexec.o \
-- execServer.o exec_startupServer.o \
-+ execServer.o exec_startupServer.o exec_experimentalServer.o \
- $(gzip-objects) $(bzip2-objects)
- gzip-sources = unzip.c util.c inflate.c
- gzip-objects = $(gzip-sources:%.c=%.o)
+- execServer.o exec_startupServer.o
++ execServer.o exec_startupServer.o exec_experimentalServer.o
+
+ target = exec
+ #targets = exec exec.static
@@ -37,6 +37,7 @@
OTHERLIBS = -lpthread
diff --git a/debian/patches/exec_filename_fs.patch b/debian/patches/exec_filename_fs.patch
index a4b5589a..b92a13a5 100644
--- a/debian/patches/exec_filename_fs.patch
+++ b/debian/patches/exec_filename_fs.patch
@@ -218,8 +218,8 @@ Index: hurd-debian/init/init.c
/* Start and maintain hurd core servers and system run state
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-- 2005, 2008 Free Software Foundation, Inc.
-+ 2005, 2008, 2010 Free Software Foundation, Inc.
+- 2005, 2008, 2013 Free Software Foundation, Inc.
++ 2005, 2008, 2010, 2013 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
The GNU Hurd is free software; you can redistribute it and/or modify
@@ -336,9 +336,9 @@ Index: hurd-debian/init/init.c
+ default_ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+
+ proc_mark_important (default_ports[INIT_PORT_PROC]);
mach_port_deallocate (mach_task_self (), default_ports[INIT_PORT_PROC]);
mach_port_deallocate (mach_task_self (), file);
- if (err)
Index: hurd-debian/libdiskfs/boot-start.c
===================================================================
--- hurd-debian.orig/libdiskfs/boot-start.c 2013-06-19 23:32:37.000000000 +0000
diff --git a/debian/patches/ext2fs_large_stores.patch b/debian/patches/ext2fs_large_stores.patch
deleted file mode 100644
index f65ec760..00000000
--- a/debian/patches/ext2fs_large_stores.patch
+++ /dev/null
@@ -1,2274 +0,0 @@
-Support for >2GB volumes
-
-XXX: this adds a parameter to pager_create and diskfs_start_disk_pager
----
- console/pager.c | 10
- ext2fs/balloc.c | 57 +++--
- ext2fs/ext2_fs.h | 3
- ext2fs/ext2fs.c | 8
- ext2fs/ext2fs.h | 145 +++++++++++--
- ext2fs/getblk.c | 31 +-
- ext2fs/hyper.c | 34 ++-
- ext2fs/ialloc.c | 41 +++
- ext2fs/inode.c | 58 +++--
- ext2fs/pager.c | 497 +++++++++++++++++++++++++++++++++++++++++++----
- ext2fs/pokel.c | 41 +++
- ext2fs/truncate.c | 11 -
- fatfs/pager.c | 11 -
- isofs/pager.c | 12 -
- libdiskfs/disk-pager.c | 6
- libdiskfs/diskfs-pager.h | 3
- libpager/data-request.c | 17 -
- libpager/data-return.c | 78 +++++--
- libpager/pager-create.c | 4
- libpager/pager.h | 29 ++
- libpager/priv.h | 1
- storeio/pager.c | 9
- tmpfs/pager-stubs.c | 8
- ufs/pager.c | 11 -
- 24 files changed, 940 insertions(+), 185 deletions(-)
-
-Index: hurd-debian/console/pager.c
-===================================================================
---- hurd-debian.orig/console/pager.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/console/pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -94,6 +94,14 @@
- }
-
-
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page)
-+{
-+ assert (!"unrequested notification on eviction");
-+}
-+
-+
- /* Tell how big the file is. */
- error_t
- pager_report_extent (struct user_pager_info *upi,
-@@ -159,7 +167,7 @@
-
- /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */
- user_pager->pager = pager_create (upi, pager_bucket,
-- 1, MEMORY_OBJECT_COPY_DELAY);
-+ 1, MEMORY_OBJECT_COPY_DELAY, 0);
- if (!user_pager->pager)
- {
- free (upi);
-Index: hurd-debian/ext2fs/balloc.c
-===================================================================
---- hurd-debian.orig/ext2fs/balloc.c 2012-07-10 01:36:36.000000000 +0000
-+++ hurd-debian/ext2fs/balloc.c 2012-07-10 01:39:22.000000000 +0000
-@@ -92,7 +92,7 @@
- block, count);
- }
- gdp = group_desc (block_group);
-- bh = bptr (gdp->bg_block_bitmap);
-+ bh = disk_cache_block_ref (gdp->bg_block_bitmap);
-
- if (in_range (gdp->bg_block_bitmap, block, gcount) ||
- in_range (gdp->bg_inode_bitmap, block, gcount) ||
-@@ -114,6 +114,7 @@
- }
-
- record_global_poke (bh);
-+ disk_cache_block_ref_ptr (gdp);
- record_global_poke (gdp);
-
- block += gcount;
-@@ -139,7 +140,7 @@
- block_t prealloc_goal,
- block_t *prealloc_count, block_t *prealloc_block)
- {
-- char *bh;
-+ char *bh = 0;
- char *p, *r;
- int i, j, k, tmp;
- unsigned long lmap;
-@@ -164,9 +165,10 @@
-
- ext2_debug ("goal=%u", goal);
-
--repeat:
-+ repeat:
-+ assert (! bh);
- /*
-- * First, test whether the goal block is free.
-+ * First, test whether the goal block is free.
- */
- if (goal < sblock->s_first_data_block || goal >= sblock->s_blocks_count)
- goal = sblock->s_first_data_block;
-@@ -179,7 +181,7 @@
- if (j)
- goal_attempts++;
- #endif
-- bh = bptr (gdp->bg_block_bitmap);
-+ bh = disk_cache_block_ref (gdp->bg_block_bitmap);
-
- ext2_debug ("goal is at %d:%d", i, j);
-
-@@ -194,8 +196,8 @@
- if (j)
- {
- /*
-- * The goal was occupied; search forward for a free
-- * block within the next 32 blocks
-+ * The goal was occupied; search forward for a free
-+ * block within the next 32 blocks
- */
- if ((j & 31) == 31)
- lmap = 0;
-@@ -245,13 +247,16 @@
- j = k;
- goto got_block;
- }
-+
-+ disk_cache_block_deref (bh);
-+ bh = 0;
- }
-
- ext2_debug ("bit not found in block group %d", i);
-
- /*
-- * Now search the rest of the groups. We assume that
-- * i and gdp correctly point to the last group visited.
-+ * Now search the rest of the groups. We assume that
-+ * i and gdp correctly point to the last group visited.
- */
- for (k = 0; k < groups_count; k++)
- {
-@@ -267,7 +272,8 @@
- pthread_spin_unlock (&global_lock);
- return 0;
- }
-- bh = bptr (gdp->bg_block_bitmap);
-+ assert (! bh);
-+ bh = disk_cache_block_ref (gdp->bg_block_bitmap);
- r = memscan (bh, 0, sblock->s_blocks_per_group >> 3);
- j = (r - bh) << 3;
- if (j < sblock->s_blocks_per_group)
-@@ -277,21 +283,25 @@
- sblock->s_blocks_per_group);
- if (j >= sblock->s_blocks_per_group)
- {
-+ disk_cache_block_deref (bh);
-+ bh = 0;
- ext2_error ("free blocks count corrupted for block group %d", i);
- pthread_spin_unlock (&global_lock);
- return 0;
- }
-
--search_back:
-+ search_back:
-+ assert (bh);
- /*
-- * We have succeeded in finding a free byte in the block
-- * bitmap. Now search backwards up to 7 bits to find the
-- * start of this group of free blocks.
-+ * We have succeeded in finding a free byte in the block
-+ * bitmap. Now search backwards up to 7 bits to find the
-+ * start of this group of free blocks.
- */
- for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh); k++, j--);
-
--got_block:
--
-+ got_block:
-+ assert (bh);
-+
- ext2_debug ("using block group %d (%d)", i, gdp->bg_free_blocks_count);
-
- tmp = j + i * sblock->s_blocks_per_group + sblock->s_first_data_block;
-@@ -304,6 +314,8 @@
- if (set_bit (j, bh))
- {
- ext2_warning ("bit already set for block %d", j);
-+ disk_cache_block_deref (bh);
-+ bh = 0;
- goto repeat;
- }
-
-@@ -320,7 +332,7 @@
- ext2_debug ("found bit %d", j);
-
- /*
-- * Do block preallocation now if required.
-+ * Do block preallocation now if required.
- */
- #ifdef EXT2_PREALLOCATE
- if (prealloc_goal)
-@@ -351,6 +363,7 @@
- j = tmp;
-
- record_global_poke (bh);
-+ bh = 0;
-
- if (j >= sblock->s_blocks_count)
- {
-@@ -363,12 +376,14 @@
- j, goal_hits, goal_attempts);
-
- gdp->bg_free_blocks_count--;
-+ disk_cache_block_ref_ptr (gdp);
- record_global_poke (gdp);
-
- sblock->s_free_blocks_count--;
- sblock_dirty = 1;
-
- sync_out:
-+ assert (! bh);
- pthread_spin_unlock (&global_lock);
- alloc_sync (0);
-
-@@ -390,9 +405,12 @@
- gdp = NULL;
- for (i = 0; i < groups_count; i++)
- {
-+ void *bh;
- gdp = group_desc (i);
- desc_count += gdp->bg_free_blocks_count;
-- x = count_free (bptr (gdp->bg_block_bitmap), block_size);
-+ bh = disk_cache_block_ref (gdp->bg_block_bitmap);
-+ x = count_free (bh, block_size);
-+ disk_cache_block_deref (bh);
- printf ("group %d: stored = %d, counted = %lu",
- i, gdp->bg_free_blocks_count, x);
- bitmap_count += x;
-@@ -453,7 +471,7 @@
-
- gdp = group_desc (i);
- desc_count += gdp->bg_free_blocks_count;
-- bh = bptr (gdp->bg_block_bitmap);
-+ bh = disk_cache_block_ref (gdp->bg_block_bitmap);
-
- if (!EXT2_HAS_RO_COMPAT_FEATURE (sblock,
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
-@@ -479,6 +497,7 @@
- ext2_error ("block #%d of the inode table in group %d is marked free", j, i);
-
- x = count_free (bh, block_size);
-+ disk_cache_block_deref (bh);
- if (gdp->bg_free_blocks_count != x)
- ext2_error ("wrong free blocks count for group %d,"
- " stored = %d, counted = %lu",
-Index: hurd-debian/ext2fs/ext2_fs.h
-===================================================================
---- hurd-debian.orig/ext2fs/ext2_fs.h 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/ext2_fs.h 2012-07-10 01:39:22.000000000 +0000
-@@ -25,7 +25,8 @@
- /*
- * Define EXT2FS_DEBUG to produce debug messages
- */
--#undef EXT2FS_DEBUG
-+/* #undef EXT2FS_DEBUG */
-+#define EXT2FS_DEBUG
-
- /*
- * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
-Index: hurd-debian/ext2fs/ext2fs.c
-===================================================================
---- hurd-debian.orig/ext2fs/ext2fs.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/ext2fs.c 2012-07-10 01:39:22.000000000 +0000
-@@ -106,7 +106,7 @@
- if (values == 0)
- return ENOMEM;
- state->hook = values;
-- bzero (values, sizeof *values);
-+ memset (values, 0, sizeof *values);
- values->sb_block = SBLOCK_BLOCK;
- break;
-
-@@ -181,9 +181,9 @@
- /* Map the entire disk. */
- create_disk_pager ();
-
-- pokel_init (&global_pokel, diskfs_disk_pager, disk_image);
-+ pokel_init (&global_pokel, diskfs_disk_pager, disk_cache);
-
-- get_hypermetadata();
-+ map_hypermetadata ();
-
- inode_init ();
-
-@@ -211,6 +211,8 @@
- {
- pokel_flush (&global_pokel);
- pager_flush (diskfs_disk_pager, 1);
-+ sblock = 0;
- get_hypermetadata ();
-+ map_hypermetadata ();
- return 0;
- }
-Index: hurd-debian/ext2fs/ext2fs.h
-===================================================================
---- hurd-debian.orig/ext2fs/ext2fs.h 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/ext2fs.h 2012-07-10 01:39:22.000000000 +0000
-@@ -23,7 +23,9 @@
- #include <hurd/pager.h>
- #include <hurd/fshelp.h>
- #include <hurd/iohelp.h>
-+#include <hurd/store.h>
- #include <hurd/diskfs.h>
-+#include <hurd/ihash.h>
- #include <assert.h>
- #include <pthread.h>
- #include <sys/mman.h>
-@@ -195,6 +197,8 @@
- /* ---------------------------------------------------------------- */
- /* pager.c */
-
-+#define DISK_CACHE_BLOCKS 65536
-+
- #include <hurd/diskfs-pager.h>
-
- /* Set up the disk pager. */
-@@ -218,10 +222,54 @@
- /* What the user specified. */
- extern struct store_parsed *store_parsed;
-
--/* Mapped image of the disk. */
--extern void *disk_image;
-+/* Mapped image of cached blocks of the disk. */
-+extern void *disk_cache;
-+extern store_offset_t disk_cache_size;
-+extern int disk_cache_blocks;
-+
-+#define DC_INCORE 0x01 /* Not in core. */
-+#define DC_UNTOUCHED 0x02 /* Not touched by disk_pager_read_paged
-+ or disk_cache_block_ref. */
-+#define DC_FIXED 0x04 /* Must not be re-associated. */
-+
-+/* Flags that forbid re-association of page. DC_UNTOUCHED is included
-+ because this flag is used only when page is already to be
-+ re-associated, so it's not good candidate for another
-+ remapping. */
-+#define DC_DONT_REUSE (DC_INCORE | DC_UNTOUCHED | DC_FIXED)
-+
-+#define DC_NO_BLOCK ((block_t) -1L)
-+
-+#ifndef NDEBUG
-+#define DISK_CACHE_LAST_READ_XOR 0xDEADBEEF
-+#endif
-
--/* Our in-core copy of the super-block (pointer into the disk_image). */
-+/* Disk cache blocks' meta info. */
-+struct disk_cache_info
-+{
-+ block_t block;
-+ uint16_t flags;
-+ uint16_t ref_count;
-+#ifndef NDEBUG
-+ block_t last_read, last_read_xor;
-+#endif
-+};
-+
-+/* block num --> pointer to in-memory block */
-+extern hurd_ihash_t disk_cache_bptr;
-+/* Metadata about cached block. */
-+extern struct disk_cache_info *disk_cache_info;
-+/* Lock for these mappings */
-+extern struct mutex disk_cache_lock;
-+/* Fired when a re-association is done. */
-+extern struct condition disk_cache_reassociation;
-+
-+void *disk_cache_block_ref (block_t block);
-+void disk_cache_block_ref_ptr (void *ptr);
-+void disk_cache_block_deref (void *ptr);
-+int disk_cache_block_is_ref (block_t block);
-+
-+/* Our in-core copy of the super-block (pointer into the disk_cache). */
- struct ext2_super_block *sblock;
- /* True if sblock has been modified. */
- int sblock_dirty;
-@@ -251,6 +299,9 @@
-
- /* Get the superblock from the disk, & setup various global info from it. */
- void get_hypermetadata ();
-+
-+/* Map `sblock' and `group_desc_image' pointers to disk cache. */
-+void map_hypermetadata ();
-
- /* ---------------------------------------------------------------- */
- /* Random stuff calculated from the super block. */
-@@ -274,21 +325,51 @@
- unsigned long next_generation;
-
- /* ---------------------------------------------------------------- */
--/* Functions for looking inside disk_image */
-+/* Functions for looking inside disk_cache */
-
--#define trunc_block(offs) (((offs) >> log2_block_size) << log2_block_size)
-+#define trunc_block(offs) \
-+ ((off_t) ((offs) >> log2_block_size) << log2_block_size)
- #define round_block(offs) \
-- ((((offs) + block_size - 1) >> log2_block_size) << log2_block_size)
-+ ((off_t) (((offs) + block_size - 1) >> log2_block_size) << log2_block_size)
-
- /* block num --> byte offset on disk */
--#define boffs(block) ((block) << log2_block_size)
-+#define boffs(block) ((off_t) (block) << log2_block_size)
- /* byte offset on disk --> block num */
- #define boffs_block(offs) ((offs) >> log2_block_size)
-
-+/* pointer to in-memory block -> index in disk_cache_info */
-+#define bptr_index(ptr) (((char *)ptr - (char *)disk_cache) >> log2_block_size)
-+
- /* byte offset on disk --> pointer to in-memory block */
--#define boffs_ptr(offs) (((char *)disk_image) + (offs))
-+EXT2FS_EI char *
-+boffs_ptr (off_t offset)
-+{
-+ block_t block = boffs_block (offset);
-+ mutex_lock (&disk_cache_lock);
-+ char *ptr = hurd_ihash_find (disk_cache_bptr, block);
-+ mutex_unlock (&disk_cache_lock);
-+ assert (ptr);
-+ ptr += offset % block_size;
-+ ext2_debug ("(%Ld) = %p", offset, ptr);
-+ return ptr;
-+}
-+
- /* pointer to in-memory block --> byte offset on disk */
--#define bptr_offs(ptr) ((char *)(ptr) - ((char *)disk_image))
-+EXT2FS_EI off_t
-+bptr_offs (void *ptr)
-+{
-+ vm_offset_t mem_offset = (char *)ptr - (char *)disk_cache;
-+ off_t offset;
-+ assert (mem_offset < disk_cache_size);
-+ mutex_lock (&disk_cache_lock);
-+ offset = (off_t) disk_cache_info[boffs_block (mem_offset)].block
-+ << log2_block_size;
-+ assert (offset || mem_offset < block_size);
-+ offset += mem_offset % block_size;
-+ mutex_unlock (&disk_cache_lock);
-+ ext2_debug ("(%p) = %Ld", ptr, offset);
-+ return offset;
-+}
-
- /* block num --> pointer to in-memory block */
- #define bptr(block) boffs_ptr(boffs(block))
-@@ -308,14 +389,24 @@
- #if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI)
- /* Convert an inode number to the dinode on disk. */
- EXT2FS_EI struct ext2_inode *
--dino (ino_t inum)
-+dino_ref (ino_t inum)
- {
- unsigned long inodes_per_group = sblock->s_inodes_per_group;
- unsigned long bg_num = (inum - 1) / inodes_per_group;
- unsigned long group_inum = (inum - 1) % inodes_per_group;
-- struct ext2_group_desc *bg = group_desc(bg_num);
-+ struct ext2_group_desc *bg = group_desc (bg_num);
- block_t block = bg->bg_inode_table + (group_inum / inodes_per_block);
-- return ((struct ext2_inode *)bptr(block)) + group_inum % inodes_per_block;
-+ struct ext2_inode *inode = disk_cache_block_ref (block);
-+ inode += group_inum % inodes_per_block;
-+ ext2_debug ("(%qd) = %p", inum, inode);
-+ return inode;
-+}
-+
-+EXT2FS_EI void
-+dino_deref (struct ext2_inode *inode)
-+{
-+ ext2_debug ("(%p)", inode);
-+ disk_cache_block_deref (inode);
- }
- #endif /* Use extern inlines. */
-
-@@ -377,27 +468,38 @@
- EXT2FS_EI void
- record_global_poke (void *ptr)
- {
-- int boffs = trunc_block (bptr_offs (ptr));
-- global_block_modified (boffs_block (boffs));
-- pokel_add (&global_pokel, boffs_ptr(boffs), block_size);
-+ block_t block = boffs_block (bptr_offs (ptr));
-+ void *block_ptr = bptr (block);
-+ ext2_debug ("(%p = %p)", ptr, block_ptr);
-+ assert (disk_cache_block_is_ref (block));
-+ global_block_modified (block);
-+ pokel_add (&global_pokel, block_ptr, block_size);
- }
-
- /* This syncs a modification to a non-file block. */
- EXT2FS_EI void
- sync_global_ptr (void *bptr, int wait)
- {
-- vm_offset_t boffs = trunc_block (bptr_offs (bptr));
-- global_block_modified (boffs_block (boffs));
-- pager_sync_some (diskfs_disk_pager, trunc_page (boffs), vm_page_size, wait);
-+ block_t block = boffs_block (bptr_offs (bptr));
-+ void *block_ptr = bptr (block);
-+ ext2_debug ("(%p -> %u)", bptr, (block_t)block);
-+ global_block_modified (block);
-+ disk_cache_block_deref (block_ptr);
-+ pager_sync_some (diskfs_disk_pager,
-+ block_ptr - disk_cache, block_size, wait);
-+
- }
-
- /* This records a modification to one of a file's indirect blocks. */
- EXT2FS_EI void
- record_indir_poke (struct node *node, void *ptr)
- {
-- int boffs = trunc_block (bptr_offs (ptr));
-- global_block_modified (boffs_block (boffs));
-- pokel_add (&node->dn->indir_pokel, boffs_ptr(boffs), block_size);
-+ block_t block = boffs_block (bptr_offs (ptr));
-+ void *block_ptr = bptr (block);
-+ ext2_debug ("(%d, %p)", (int)node->cache_id, ptr);
-+ assert (disk_cache_block_is_ref (block));
-+ global_block_modified (block);
-+ pokel_add (&node->dn->indir_pokel, block_ptr, block_size);
- }
-
- /* ---------------------------------------------------------------- */
-@@ -405,6 +507,7 @@
- EXT2FS_EI void
- sync_global (int wait)
- {
-+ ext2_debug ("%d", wait);
- pokel_sync (&global_pokel, wait);
- }
-
-Index: hurd-debian/ext2fs/getblk.c
-===================================================================
---- hurd-debian.orig/ext2fs/getblk.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/getblk.c 2012-07-10 01:39:22.000000000 +0000
-@@ -52,7 +52,7 @@
- if (node->dn->info.i_prealloc_count)
- {
- int i = node->dn->info.i_prealloc_count;
-- ext2_debug ("discarding %d prealloced blocks for inode %d",
-+ ext2_debug ("discarding %d prealloced blocks for inode %Ld",
- i, node->cache_id);
- node->dn->info.i_prealloc_count = 0;
- ext2_free_blocks (node->dn->info.i_prealloc_block, i);
-@@ -104,8 +104,8 @@
-
- if (result && zero)
- {
-- char *bh = bptr (result);
-- bzero (bh, block_size);
-+ char *bh = disk_cache_block_ref (result);
-+ memset (bh, 0, block_size);
- record_indir_poke (node, bh);
- }
-
-@@ -122,6 +122,8 @@
- block_t hint;
- #endif
-
-+ assert (0 <= nr && nr < EXT2_N_BLOCKS);
-+
- *result = node->dn->info.i_data[nr];
- if (*result)
- return 0;
-@@ -180,14 +182,20 @@
- {
- int i;
- block_t goal = 0;
-- block_t *bh = (block_t *)bptr (block);
-+ block_t *bh = (block_t *)disk_cache_block_ref (block);
-
- *result = bh[nr];
- if (*result)
-- return 0;
-+ {
-+ disk_cache_block_deref (bh);
-+ return 0;
-+ }
-
- if (!create)
-- return EINVAL;
-+ {
-+ disk_cache_block_deref (bh);
-+ return EINVAL;
-+ }
-
- if (node->dn->info.i_next_alloc_block == new_block)
- goal = node->dn->info.i_next_alloc_goal;
-@@ -207,7 +215,10 @@
-
- *result = ext2_alloc_block (node, goal, zero);
- if (!*result)
-- return ENOSPC;
-+ {
-+ disk_cache_block_deref (bh);
-+ return ENOSPC;
-+ }
-
- bh[nr] = *result;
-
-@@ -243,9 +254,9 @@
- return EIO;
- }
- /*
-- * If this is a sequential block allocation, set the next_alloc_block
-- * to this block now so that all the indblock and data block
-- * allocations use the same goal zone
-+ * If this is a sequential block allocation, set the next_alloc_block
-+ * to this block now so that all the indblock and data block
-+ * allocations use the same goal zone
- */
-
- ext2_debug ("block = %u, next = %u, goal = %u", block,
-Index: hurd-debian/ext2fs/hyper.c
-===================================================================
---- hurd-debian.orig/ext2fs/hyper.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/hyper.c 2012-07-10 01:39:22.000000000 +0000
-@@ -58,12 +58,15 @@
- void
- get_hypermetadata (void)
- {
-- error_t err = diskfs_catch_exception ();
-- if (err)
-- ext2_panic ("can't read superblock: %s", strerror (err));
--
-- sblock = (struct ext2_super_block *) boffs_ptr (SBLOCK_OFFS);
-+ error_t err;
-+ size_t read = 0;
-
-+ assert (! sblock);
-+ err = store_read (store, SBLOCK_OFFS >> store->log2_block_size,
-+ SBLOCK_SIZE, (void **)&sblock, &read);
-+ if (err || read != SBLOCK_SIZE)
-+ ext2_panic ("Cannot read hypermetadata");
-+
- if (sblock->s_magic != EXT2_SUPER_MAGIC
- #ifdef EXT2FS_PRE_02B_COMPAT
- && sblock->s_magic != EXT2_PRE_02B_MAGIC
-@@ -152,15 +155,22 @@
-
- allocate_mod_map ();
-
-- diskfs_end_catch_exception ();
-+ /* A handy source of page-aligned zeros. */
-+ if (zeroblock == 0)
-+ zeroblock = (vm_address_t) mmap (0, block_size, PROT_READ, MAP_ANON, 0, 0);
-+
-+ munmap (sblock, SBLOCK_SIZE);
-+ sblock = NULL;
-+}
-+
-+void
-+map_hypermetadata (void)
-+{
-+ sblock = (struct ext2_super_block *) boffs_ptr (SBLOCK_OFFS);
-
- /* Cache a convenient pointer to the block group descriptors for allocation.
- These are stored in the filesystem blocks following the superblock. */
- group_desc_image = (struct ext2_group_desc *) bptr (bptr_block (sblock) + 1);
--
-- /* A handy source of page-aligned zeros. */
-- if (zeroblock == 0)
-- zeroblock = (vm_address_t) mmap (0, block_size, PROT_READ, MAP_ANON, 0, 0);
- }
-
- error_t
-@@ -183,6 +193,7 @@
- if (sblock_dirty)
- {
- sblock_dirty = 0;
-+ disk_cache_block_ref_ptr (sblock);
- record_global_poke (sblock);
- }
-
-@@ -199,7 +210,8 @@
-
- (*(readonly ? store_set_flags : store_clear_flags)) (store, STORE_READONLY);
-
-- mprotect (disk_image, store->size, PROT_READ | (readonly ? 0 : PROT_WRITE));
-+ mprotect (disk_cache, disk_cache_size,
-+ PROT_READ | (readonly ? 0 : PROT_WRITE));
-
- if (!readonly && !(sblock->s_state & EXT2_VALID_FS))
- ext2_warning ("UNCLEANED FILESYSTEM NOW WRITABLE");
-Index: hurd-debian/ext2fs/ialloc.c
-===================================================================
---- hurd-debian.orig/ext2fs/ialloc.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/ialloc.c 2012-07-10 01:39:22.000000000 +0000
-@@ -60,7 +60,7 @@
-
- assert (!diskfs_readonly);
-
-- ext2_debug ("freeing inode %u", inum);
-+ ext2_debug ("freeing inode %Lu", inum);
-
- pthread_spin_lock (&global_lock);
-
-@@ -75,22 +75,25 @@
- bit = (inum - 1) % sblock->s_inodes_per_group;
-
- gdp = group_desc (block_group);
-- bh = bptr (gdp->bg_inode_bitmap);
-+ bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
-
- if (!clear_bit (bit, bh))
- ext2_warning ("bit already cleared for inode %Ld", inum);
- else
- {
-+ disk_cache_block_ref_ptr (bh);
- record_global_poke (bh);
-
- gdp->bg_free_inodes_count++;
- if (S_ISDIR (old_mode))
- gdp->bg_used_dirs_count--;
-+ disk_cache_block_ref_ptr (gdp);
- record_global_poke (gdp);
-
- sblock->s_free_inodes_count++;
- }
-
-+ disk_cache_block_deref (bh);
- sblock_dirty = 1;
- pthread_spin_unlock (&global_lock);
- alloc_sync(0);
-@@ -111,14 +114,15 @@
- ino_t
- ext2_alloc_inode (ino_t dir_inum, mode_t mode)
- {
-- char *bh;
-+ char *bh = 0;
- int i, j, inum, avefreei;
- struct ext2_group_desc *gdp;
- struct ext2_group_desc *tmp;
-
- pthread_spin_lock (&global_lock);
-
--repeat:
-+ repeat:
-+ assert (! bh);
- gdp = NULL;
- i = 0;
-
-@@ -213,7 +217,7 @@
- return 0;
- }
-
-- bh = bptr (gdp->bg_inode_bitmap);
-+ bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
- if ((inum =
- find_first_zero_bit ((unsigned long *) bh, sblock->s_inodes_per_group))
- < sblock->s_inodes_per_group)
-@@ -221,12 +225,17 @@
- if (set_bit (inum, bh))
- {
- ext2_warning ("bit already set for inode %d", inum);
-+ disk_cache_block_deref (bh);
-+ bh = 0;
- goto repeat;
- }
- record_global_poke (bh);
-+ bh = 0;
- }
- else
- {
-+ disk_cache_block_deref (bh);
-+ bh = 0;
- if (gdp->bg_free_inodes_count != 0)
- {
- ext2_error ("free inodes count corrupted in group %d", i);
-@@ -248,15 +257,25 @@
- gdp->bg_free_inodes_count--;
- if (S_ISDIR (mode))
- gdp->bg_used_dirs_count++;
-+ disk_cache_block_ref_ptr (gdp);
- record_global_poke (gdp);
-
- sblock->s_free_inodes_count--;
- sblock_dirty = 1;
-
- sync_out:
-+ assert (! bh);
- pthread_spin_unlock (&global_lock);
- alloc_sync (0);
-
-+ /* Make sure the coming read_node won't complain about bad
-+ fields. */
-+ {
-+ struct ext2_inode *di = dino_ref (inum);
-+ memset (di, 0, sizeof *di);
-+ dino_deref (di);
-+ }
-+
- return inum;
- }
-
-@@ -353,10 +372,12 @@
- gdp = NULL;
- for (i = 0; i < groups_count; i++)
- {
-+ void *bh;
- gdp = group_desc (i);
- desc_count += gdp->bg_free_inodes_count;
-- x = count_free (bptr (gdp->bg_inode_bitmap),
-- sblock->s_inodes_per_group / 8);
-+ bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
-+ x = count_free (bh, sblock->s_inodes_per_group / 8);
-+ disk_cache_block_deref (bh);
- ext2_debug ("group %d: stored = %d, counted = %lu",
- i, gdp->bg_free_inodes_count, x);
- bitmap_count += x;
-@@ -386,10 +407,12 @@
- gdp = NULL;
- for (i = 0; i < groups_count; i++)
- {
-+ void *bh;
- gdp = group_desc (i);
- desc_count += gdp->bg_free_inodes_count;
-- x = count_free (bptr (gdp->bg_inode_bitmap),
-- sblock->s_inodes_per_group / 8);
-+ bh = disk_cache_block_ref (gdp->bg_inode_bitmap);
-+ x = count_free (bh, sblock->s_inodes_per_group / 8);
-+ disk_cache_block_deref (bh);
- if (gdp->bg_free_inodes_count != x)
- ext2_error ("wrong free inodes count in group %d, "
- "stored = %d, counted = %lu",
-Index: hurd-debian/ext2fs/inode.c
-===================================================================
---- hurd-debian.orig/ext2fs/inode.c 2012-11-26 00:23:28.000000000 +0000
-+++ hurd-debian/ext2fs/inode.c 2012-11-26 00:24:49.000000000 +0000
-@@ -92,7 +92,7 @@
- dn->dir_idx = 0;
- dn->pager = 0;
- pthread_rwlock_init (&dn->alloc_lock, NULL);
-- pokel_init (&dn->indir_pokel, diskfs_disk_pager, disk_image);
-+ pokel_init (&dn->indir_pokel, diskfs_disk_pager, disk_cache);
-
- /* Create the new node. */
- np = diskfs_make_node (dn);
-@@ -201,13 +201,17 @@
- error_t err;
- struct stat *st = &np->dn_stat;
- struct disknode *dn = np->dn;
-- struct ext2_inode *di = dino (np->cache_id);
-+ struct ext2_inode *di;
- struct ext2_inode_info *info = &dn->info;
-
-+ ext2_debug ("(%d)", np->cache_id);
-+
- err = diskfs_catch_exception ();
- if (err)
- return err;
-
-+ di = dino_ref (np->cache_id);
-+
- st->st_fstype = FSTYPE_EXT2FS;
- st->st_fsid = getpid (); /* This call is very cheap. */
- st->st_ino = np->cache_id;
-@@ -285,7 +289,9 @@
- info->i_high_size = di->i_size_high;
- if (info->i_high_size) /* XXX */
- {
-+ dino_deref (di);
- ext2_warning ("cannot handle large file inode %Ld", np->cache_id);
-+ diskfs_end_catch_exception ();
- return EFBIG;
- }
- }
-@@ -307,20 +313,12 @@
- }
- dn->info_i_translator = di->i_translator;
-
-+ dino_deref (di);
- diskfs_end_catch_exception ();
-
- if (S_ISREG (st->st_mode) || S_ISDIR (st->st_mode)
- || (S_ISLNK (st->st_mode) && st->st_blocks))
-- {
-- unsigned offset;
--
-- np->allocsize = np->dn_stat.st_size;
--
-- /* Round up to a block multiple. */
-- offset = np->allocsize & ((1 << log2_block_size) - 1);
-- if (offset > 0)
-- np->allocsize += block_size - offset;
-- }
-+ np->allocsize = round_block (np->dn_stat.st_size);
- else
- /* Allocsize should be zero for anything except directories, files, and
- long symlinks. These are the only things allowed to have any blocks
-@@ -408,7 +406,9 @@
- {
- error_t err;
- struct stat *st = &np->dn_stat;
-- struct ext2_inode *di = dino (np->cache_id);
-+ struct ext2_inode *di;
-+
-+ ext2_debug ("(%d)", np->cache_id);
-
- if (np->dn->info.i_prealloc_count)
- ext2_discard_prealloc (np);
-@@ -419,12 +419,14 @@
-
- assert (!diskfs_readonly);
-
-- ext2_debug ("writing inode %d to disk", np->cache_id);
-+ ext2_debug ("writing inode %Ld to disk", np->cache_id);
-
- err = diskfs_catch_exception ();
- if (err)
- return NULL;
-
-+ di = dino_ref (np->cache_id);
-+
- di->i_generation = st->st_gen;
-
- /* We happen to know that the stat mode bits are the same
-@@ -505,6 +507,7 @@
- diskfs_end_catch_exception ();
- np->dn_stat_dirty = 0;
-
-+ /* Leave invoking dino_deref (di) to the caller. */
- return di;
- }
- else
-@@ -674,7 +677,7 @@
- if (err)
- return err;
-
-- di = dino (np->cache_id);
-+ di = dino_ref (np->cache_id);
- blkno = di->i_translator;
-
- if (namelen && !blkno)
-@@ -687,6 +690,7 @@
- 0, 0, 0);
- if (blkno == 0)
- {
-+ dino_deref (di);
- diskfs_end_catch_exception ();
- return ENOSPC;
- }
-@@ -710,15 +714,20 @@
- np->dn_stat.st_mode &= ~S_IPTRANS;
- np->dn_set_ctime = 1;
- }
-+ else
-+ dino_deref (di);
-
- if (namelen)
- {
-+ void *blkptr;
-+
- buf[0] = namelen & 0xFF;
- buf[1] = (namelen >> 8) & 0xFF;
-- bcopy (name, buf + 2, namelen);
-+ memcpy (buf + 2, name, namelen);
-
-- bcopy (buf, bptr (blkno), block_size);
-- record_global_poke (bptr (blkno));
-+ blkptr = disk_cache_block_ref (blkno);
-+ memcpy (blkptr, buf, block_size);
-+ record_global_poke (blkptr);
-
- np->dn_stat.st_mode |= S_IPTRANS;
- np->dn_set_ctime = 1;
-@@ -736,7 +745,7 @@
- error_t err = 0;
- daddr_t blkno;
- unsigned datalen;
-- const void *transloc;
-+ void *transloc;
-
- assert (sblock->s_creator_os == EXT2_OS_HURD);
-
-@@ -744,9 +753,11 @@
- if (err)
- return err;
-
-- blkno = (dino (np->cache_id))->i_translator;
-+ struct ext2_inode *di = dino_ref (np->cache_id);
-+ blkno = di->i_translator;
-+ dino_deref (di);
- assert (blkno);
-- transloc = bptr (blkno);
-+ transloc = disk_cache_block_ref (blkno);
-
- datalen =
- ((unsigned char *)transloc)[0] + (((unsigned char *)transloc)[1] << 8);
-@@ -761,6 +772,7 @@
- memcpy (*namep, transloc + 2, datalen);
- }
-
-+ disk_cache_block_deref (transloc);
- diskfs_end_catch_exception ();
-
- *namelen = datalen;
-@@ -782,7 +794,7 @@
-
- assert (node->dn_stat.st_blocks == 0);
-
-- bcopy (target, node->dn->info.i_data, len);
-+ memcpy (node->dn->info.i_data, target, len);
- node->dn_stat.st_size = len - 1;
- node->dn_set_ctime = 1;
- node->dn_set_mtime = 1;
-@@ -799,7 +811,7 @@
-
- assert (node->dn_stat.st_size < MAX_INODE_SYMLINK);
-
-- bcopy (node->dn->info.i_data, target, node->dn_stat.st_size);
-+ memcpy (target, node->dn->info.i_data, node->dn_stat.st_size);
- return 0;
- }
-
-Index: hurd-debian/ext2fs/pager.c
-===================================================================
---- hurd-debian.orig/ext2fs/pager.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -18,17 +18,18 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-+#include <unistd.h>
- #include <string.h>
- #include <errno.h>
- #include <hurd/store.h>
- #include "ext2fs.h"
-
-+/* XXX */
-+#include "../libpager/priv.h"
-+
- /* A ports bucket to hold pager ports. */
- struct port_bucket *pager_bucket;
-
--/* Mapped image of the disk. */
--void *disk_image;
--
- pthread_spinlock_t node_to_page_lock = PTHREAD_SPINLOCK_INITIALIZER;
-
-
-@@ -165,6 +166,9 @@
- block_t pending_blocks = 0;
- int num_pending_blocks = 0;
-
-+ ext2_debug ("reading inode %Ld page %u[%d]",
-+ node->cache_id, page, vm_page_size);
-+
- /* Read the NUM_PENDING_BLOCKS blocks in PENDING_BLOCKS, into the buffer
- pointed to by BUF (allocating it if necessary) at offset OFFS. OFFS in
- adjusted by the amount read, and NUM_PENDING_BLOCKS is zeroed. Any read
-@@ -171,7 +175,8 @@
- {
- if (num_pending_blocks > 0)
- {
-- block_t dev_block = pending_blocks << log2_dev_blocks_per_fs_block;
-+ store_offset_t dev_block = (store_offset_t) pending_blocks
-+ << log2_dev_blocks_per_fs_block;
- size_t amount = num_pending_blocks << log2_block_size;
- /* The buffer we try to read into; on the first read, we pass in a
- size of zero, so that the read is guaranteed to allocate a new
-@@ -198,7 +203,7 @@
- else
- /* We've already got some buffer, so copy into it. */
- {
-- bcopy (new_buf, *buf + offs, new_len);
-+ memcpy (*buf + offs, new_buf, new_len);
- free_page_buf (new_buf); /* Return NEW_BUF to our pool. */
- STAT_INC (file_pagein_freed_bufs);
- }
-@@ -254,7 +259,7 @@
- break;
- STAT_INC (file_pagein_alloced_bufs);
- }
-- bzero (*buf + offs, block_size);
-+ memset (*buf + offs, 0, block_size);
- offs += block_size;
- }
- else
-@@ -295,16 +300,17 @@
- if (pb->num > 0)
- {
- error_t err;
-- block_t dev_block = pb->block << log2_dev_blocks_per_fs_block;
-+ store_offset_t dev_block = (store_offset_t) pb->block
-+ << log2_dev_blocks_per_fs_block;
- size_t length = pb->num << log2_block_size, amount;
-
-- ext2_debug ("writing block %u[%ld]", pb->block, pb->num);
-+ ext2_debug ("writing block %u[%Ld]", pb->block, pb->num);
-
- if (pb->offs > 0)
- /* Put what we're going to write into a page-aligned buffer. */
- {
- void *page_buf = get_page_buf ();
-- bcopy (pb->buf + pb->offs, (void *)page_buf, length);
-+ memcpy ((void *)page_buf, pb->buf + pb->offs, length);
- err = store_write (store, dev_block, page_buf, length, &amount);
- free_page_buf (page_buf);
- }
-@@ -357,7 +363,7 @@
- return 0;
- }
-
--/* Write one page for the pager backing NODE, at offset PAGE, into BUF. This
-+/* Write one page for the pager backing NODE, at OFFSET, into BUF. This
- may need to write several filesystem blocks to satisfy one page, and tries
- to consolidate the i/o if possible. */
- static error_t
-@@ -381,7 +387,7 @@
- else if (offset + left > node->allocsize)
- left = node->allocsize - offset;
-
-- ext2_debug ("writing inode %d page %d[%d]", node->cache_id, offset, left);
-+ ext2_debug ("writing inode %Ld page %u[%d]", node->cache_id, offset, left);
-
- STAT_INC (file_pageouts);
-
-@@ -409,16 +415,31 @@
- {
- error_t err;
- size_t length = vm_page_size, read = 0;
-- vm_size_t dev_end = store->size;
-+ store_offset_t offset = page, dev_end = store->size;
-
-- if (page + vm_page_size > dev_end)
-- length = dev_end - page;
-+ mutex_lock (&disk_cache_lock);
-+ int index = offset >> log2_block_size;
-+ offset = ((store_offset_t) disk_cache_info[index].block << log2_block_size)
-+ + offset % block_size;
-+ disk_cache_info[index].flags |= DC_INCORE;
-+ disk_cache_info[index].flags &=~ DC_UNTOUCHED;
-+#ifndef NDEBUG
-+ disk_cache_info[index].last_read = disk_cache_info[index].block;
-+ disk_cache_info[index].last_read_xor
-+ = disk_cache_info[index].block ^ DISK_CACHE_LAST_READ_XOR;
-+#endif
-+ ext2_debug ("(%Ld)", offset >> log2_block_size);
-+ mutex_unlock (&disk_cache_lock);
-+
-+ if (offset + vm_page_size > dev_end)
-+ length = dev_end - offset;
-
-- err = store_read (store, page >> store->log2_block_size, length, buf, &read);
-+ err = store_read (store, offset >> store->log2_block_size, length,
-+ buf, &read);
- if (read != length)
- return EIO;
- if (!err && length != vm_page_size)
-- bzero ((void *)(*buf + length), vm_page_size - length);
-+ memset ((void *)(*buf + length), 0, vm_page_size - length);
-
- *writelock = 0;
-
-@@ -430,26 +451,38 @@
- {
- error_t err = 0;
- size_t length = vm_page_size, amount;
-- vm_size_t dev_end = store->size;
-+ store_offset_t offset = page, dev_end = store->size;
-+
-+ mutex_lock (&disk_cache_lock);
-+ int index = offset >> log2_block_size;
-+ assert (disk_cache_info[index].block != DC_NO_BLOCK);
-+ offset = ((store_offset_t) disk_cache_info[index].block << log2_block_size)
-+ + offset % block_size;
-+#ifndef NDEBUG /* Not strictly needed. */
-+ assert ((disk_cache_info[index].last_read ^ DISK_CACHE_LAST_READ_XOR)
-+ == disk_cache_info[index].last_read_xor);
-+ assert (disk_cache_info[index].last_read
-+ == disk_cache_info[index].block);
-+#endif
-+ mutex_unlock (&disk_cache_lock);
-
-- if (page + vm_page_size > dev_end)
-- length = dev_end - page;
-+ if (offset + vm_page_size > dev_end)
-+ length = dev_end - offset;
-
-- ext2_debug ("writing disk page %d[%d]", page, length);
-+ ext2_debug ("writing disk page %Ld[%d]", offset, length);
-
- STAT_INC (disk_pageouts);
-
- if (modified_global_blocks)
- /* Be picky about which blocks in a page that we write. */
- {
-- vm_offset_t offs = page;
- struct pending_blocks pb;
-
- pending_blocks_init (&pb, buf);
-
- while (length > 0 && !err)
- {
-- block_t block = boffs_block (offs);
-+ block_t block = boffs_block (offset);
-
- /* We don't clear the block modified bit here because this paging
- write request may not be the same one that actually set the bit,
-@@ -467,7 +500,7 @@
- /* Otherwise just skip it. */
- err = pending_blocks_skip (&pb);
-
-- offs += block_size;
-+ offset += block_size;
- length -= block_size;
- }
-
-@@ -476,7 +509,7 @@
- }
- else
- {
-- err = store_write (store, page >> store->log2_block_size,
-+ err = store_write (store, offset >> store->log2_block_size,
- buf, length, &amount);
- if (!err && length != amount)
- err = EIO;
-@@ -484,6 +517,18 @@
-
- return err;
- }
-+
-+static void
-+disk_pager_notify_evict (vm_offset_t page)
-+{
-+ int index = page >> log2_block_size;
-+
-+ ext2_debug ("(block %u)", index);
-+
-+ mutex_lock (&disk_cache_lock);
-+ disk_cache_info[index].flags &= ~DC_INCORE;
-+ mutex_unlock (&disk_cache_lock);
-+}
-
- /* Satisfy a pager read request for either the disk pager or file pager
- PAGER, to the page at offset PAGE into BUF. WRITELOCK should be set if
-@@ -493,9 +538,11 @@
- vm_address_t *buf, int *writelock)
- {
- if (pager->type == DISK)
-- return disk_pager_read_page (page, (void **)buf, writelock);
-+ return disk_pager_read_page (page, (void **)buf,
-+ writelock);
- else
-- return file_pager_read_page (pager->node, page, (void **)buf, writelock);
-+ return file_pager_read_page (pager->node, page, (void **)buf,
-+ writelock);
- }
-
- /* Satisfy a pager write request for either the disk pager or file pager
-@@ -509,6 +556,14 @@
- else
- return file_pager_write_page (pager->node, page, (void *)buf);
- }
-+
-+void
-+pager_notify_evict (struct user_pager_info *pager, vm_offset_t page)
-+{
-+ if (pager->type == DISK)
-+ disk_pager_notify_evict (page);
-+}
-+
-
- /* Make page PAGE writable, at least up to ALLOCSIZE. This function and
- diskfs_grow are the only places that blocks are actually added to the
-@@ -558,10 +613,10 @@
-
- #ifdef EXT2FS_DEBUG
- if (dn->last_page_partially_writable)
-- ext2_debug ("made page %u[%lu] in inode %d partially writable",
-+ ext2_debug ("made page %u[%Lu] in inode %Ld partially writable",
- page, node->allocsize - page, node->cache_id);
- else
-- ext2_debug ("made page %u[%u] in inode %d writable",
-+ ext2_debug ("made page %u[%u] in inode %Ld writable",
- page, vm_page_size, node->cache_id);
- #endif
-
-@@ -619,8 +674,8 @@
- block_t old_page_end_block =
- round_page (old_size) >> log2_block_size;
-
-- ext2_debug ("growing inode %d to %lu bytes (from %lu)", node->cache_id,
-- new_size, old_size);
-+ ext2_debug ("growing inode %Ld to %Lu bytes (from %Lu)",
-+ node->cache_id, new_size, old_size);
-
- if (dn->last_page_partially_writable
- && old_page_end_block > end_block)
-@@ -656,11 +711,11 @@
-
- STAT_INC (file_grows);
-
-- ext2_debug ("new size: %ld%s.", new_size,
-+ ext2_debug ("new size: %Lu%s.", new_size,
- dn->last_page_partially_writable
- ? " (last page writable)": "");
- if (err)
-- ext2_warning ("inode=%Ld, target=%Ld: %s",
-+ ext2_warning ("inode=%Ld, target=%Lu: %s",
- node->cache_id, new_size, strerror (err));
-
- node->allocsize = new_size;
-@@ -765,6 +820,374 @@
- {
- }
-
-+/* Cached blocks from disk. */
-+void *disk_cache;
-+
-+/* DISK_CACHE size in bytes and blocks. */
-+store_offset_t disk_cache_size;
-+int disk_cache_blocks;
-+
-+/* block num --> pointer to in-memory block */
-+hurd_ihash_t disk_cache_bptr;
-+/* Cached blocks' info. */
-+struct disk_cache_info *disk_cache_info;
-+/* Hint index for which cache block to reuse next. */
-+int disk_cache_hint;
-+/* Lock for these structures. */
-+struct mutex disk_cache_lock;
-+/* Fired when a re-association is done. */
-+struct condition disk_cache_reassociation;
-+
-+/* Finish mapping initialization. */
-+static void
-+disk_cache_init (void)
-+{
-+ if (block_size != vm_page_size)
-+ ext2_panic ("Block size %d != vm_page_size %d",
-+ block_size, vm_page_size);
-+
-+ mutex_init (&disk_cache_lock);
-+ condition_init (&disk_cache_reassociation);
-+
-+ /* Allocate space for block num -> in-memory pointer mapping. */
-+ if (hurd_ihash_create (&disk_cache_bptr, HURD_IHASH_NO_LOCP))
-+ ext2_panic ("Can't allocate memory for disk_pager_bptr");
-+
-+ /* Allocate space for disk cache blocks' info. */
-+ disk_cache_info = malloc ((sizeof *disk_cache_info) * disk_cache_blocks);
-+ if (!disk_cache_info)
-+ ext2_panic ("Cannot allocate space for disk cache info");
-+
-+ /* Initialize disk_cache_info. */
-+ for (int i = 0; i < disk_cache_blocks; i++)
-+ {
-+ disk_cache_info[i].block = DC_NO_BLOCK;
-+ disk_cache_info[i].flags = 0;
-+ disk_cache_info[i].ref_count = 0;
-+#ifndef NDEBUG
-+ disk_cache_info[i].last_read = DC_NO_BLOCK;
-+ disk_cache_info[i].last_read_xor
-+ = DC_NO_BLOCK ^ DISK_CACHE_LAST_READ_XOR;
-+#endif
-+ }
-+ disk_cache_hint = 0;
-+
-+ /* Map the superblock and the block group descriptors. */
-+ block_t fixed_first = boffs_block (SBLOCK_OFFS);
-+ block_t fixed_last = fixed_first
-+ + (round_block ((sizeof *group_desc_image) * groups_count)
-+ >> log2_block_size);
-+ ext2_debug ("%d-%d\n", fixed_first, fixed_last);
-+ assert (fixed_last - fixed_first + 1 <= (block_t)disk_cache_blocks + 3);
-+ for (block_t i = fixed_first; i <= fixed_last; i++)
-+ {
-+ disk_cache_block_ref (i);
-+ assert (disk_cache_info[i-fixed_first].block == i);
-+ disk_cache_info[i-fixed_first].flags |= DC_FIXED;
-+ }
-+}
-+
-+static void
-+disk_cache_return_unused (void)
-+{
-+ int index;
-+
-+ /* XXX: Touch all pages. It seems that sometimes GNU Mach "forgets"
-+ to notify us about evicted pages. Disk cache must be
-+ unlocked. */
-+ for (vm_offset_t i = 0; i < disk_cache_size; i += vm_page_size)
-+ *(volatile char *)(disk_cache + i);
-+
-+ /* Release some references to cached blocks. */
-+ pokel_sync (&global_pokel, 1);
-+
-+ /* Return unused pages that are in core. */
-+ int pending_begin = -1, pending_end = -1;
-+ mutex_lock (&disk_cache_lock);
-+ for (index = 0; index < disk_cache_blocks; index++)
-+ if (! (disk_cache_info[index].flags & (DC_DONT_REUSE & ~DC_INCORE))
-+ && ! disk_cache_info[index].ref_count)
-+ {
-+ ext2_debug ("return %u -> %d",
-+ disk_cache_info[index].block, index);
-+ if (index != pending_end)
-+ {
-+ /* Return previous region, if there is such, ... */
-+ if (pending_end >= 0)
-+ {
-+ mutex_unlock (&disk_cache_lock);
-+ pager_return_some (diskfs_disk_pager,
-+ pending_begin * vm_page_size,
-+ (pending_end - pending_begin)
-+ * vm_page_size,
-+ 1);
-+ mutex_lock (&disk_cache_lock);
-+ }
-+ /* ... and start new region. */
-+ pending_begin = index;
-+ }
-+ pending_end = index + 1;
-+ }
-+
-+ mutex_unlock (&disk_cache_lock);
-+
-+ /* Return last region, if there is such. */
-+ if (pending_end >= 0)
-+ pager_return_some (diskfs_disk_pager,
-+ pending_begin * vm_page_size,
-+ (pending_end - pending_begin) * vm_page_size,
-+ 1);
-+ else
-+ {
-+ printf ("ext2fs: disk cache is starving\n");
-+
-+ /* Give it some time. This should happen rarely. */
-+ sleep (1);
-+ }
-+}
-+
-+/* Map block and return pointer to it. */
-+void *
-+disk_cache_block_ref (block_t block)
-+{
-+ int index;
-+ void *bptr;
-+
-+ assert (0 <= block && block < store->size >> log2_block_size);
-+
-+ ext2_debug ("(%u)", block);
-+
-+ mutex_lock (&disk_cache_lock);
-+
-+ bptr = hurd_ihash_find (disk_cache_bptr, block);
-+ if (bptr)
-+ /* Already mapped. */
-+ {
-+ index = bptr_index (bptr);
-+
-+ /* In process of re-associating? */
-+ if (disk_cache_info[index].flags & DC_UNTOUCHED)
-+ {
-+ /* Wait re-association to finish. */
-+ condition_wait (&disk_cache_reassociation, &disk_cache_lock);
-+ mutex_unlock (&disk_cache_lock);
-+
-+#if 0
-+ printf ("Re-association -- wait finished.\n");
-+#endif
-+
-+ /* Try again. */
-+ return disk_cache_block_ref (block); /* tail recursion */
-+ }
-+
-+ /* Just increment reference and return. */
-+ assert (disk_cache_info[index].ref_count + 1
-+ > disk_cache_info[index].ref_count);
-+ disk_cache_info[index].ref_count++;
-+
-+ ext2_debug ("cached %u -> %d (ref_count = %d, flags = 0x%x, ptr = %p)",
-+ disk_cache_info[index].block, index,
-+ disk_cache_info[index].ref_count,
-+ disk_cache_info[index].flags, bptr);
-+
-+ mutex_unlock (&disk_cache_lock);
-+
-+ return bptr;
-+ }
-+
-+ /* Search for a block that is not in core and is not referenced. */
-+ index = disk_cache_hint;
-+ while ((disk_cache_info[index].flags & DC_DONT_REUSE)
-+ || (disk_cache_info[index].ref_count))
-+ {
-+ ext2_debug ("reject %u -> %d (ref_count = %d, flags = 0x%x)",
-+ disk_cache_info[index].block, index,
-+ disk_cache_info[index].ref_count,
-+ disk_cache_info[index].flags);
-+
-+ /* Just move to next block. */
-+ index++;
-+ if (index >= disk_cache_blocks)
-+ index -= disk_cache_blocks;
-+
-+ /* If we return to where we started, than there is no suitable
-+ block. */
-+ if (index == disk_cache_hint)
-+ break;
-+ }
-+
-+ /* The next place in the disk cache becomes the current hint. */
-+ disk_cache_hint = index + 1;
-+ if (disk_cache_hint >= disk_cache_blocks)
-+ disk_cache_hint -= disk_cache_blocks;
-+
-+ /* Is suitable place found? */
-+ if ((disk_cache_info[index].flags & DC_DONT_REUSE)
-+ || disk_cache_info[index].ref_count)
-+ /* No place is found. Try to release some blocks and try
-+ again. */
-+ {
-+ ext2_debug ("flush %u -> %d", disk_cache_info[index].block, index);
-+
-+ mutex_unlock (&disk_cache_lock);
-+
-+ disk_cache_return_unused ();
-+
-+ return disk_cache_block_ref (block); /* tail recursion */
-+ }
-+
-+ /* Suitable place is found. */
-+
-+ /* Calculate pointer to data. */
-+ bptr = (char *)disk_cache + (index << log2_block_size);
-+ ext2_debug ("map %u -> %d (%p)", block, index, bptr);
-+
-+ /* This pager_return_some is used only to set PM_FORCEREAD for the
-+ page. DC_UNTOUCHED is set so that we catch if someone has
-+ referenced the block while we didn't hold disk_cache_lock. */
-+ disk_cache_info[index].flags |= DC_UNTOUCHED;
-+
-+#if 0 /* XXX: Let's see if this is needed at all. */
-+
-+ mutex_unlock (&disk_cache_lock);
-+ pager_return_some (diskfs_disk_pager, bptr - disk_cache, vm_page_size, 1);
-+ mutex_lock (&disk_cache_lock);
-+
-+ /* Has someone used our bptr? Has someone mapped requested block
-+ while we have unlocked disk_cache_lock? If so, environment has
-+ changed and we have to restart operation. */
-+ if ((! (disk_cache_info[index].flags & DC_UNTOUCHED))
-+ || hurd_ihash_find (disk_cache_bptr, block))
-+ {
-+ mutex_unlock (&disk_cache_lock);
-+ return disk_cache_block_ref (block); /* tail recursion */
-+ }
-+
-+#elif 0
-+
-+ /* XXX: Use libpager internals. */
-+
-+ mutex_lock (&diskfs_disk_pager->interlock);
-+ int page = (bptr - disk_cache) / vm_page_size;
-+ assert (page >= 0);
-+ int is_incore = (page < diskfs_disk_pager->pagemapsize
-+ && (diskfs_disk_pager->pagemap[page] & PM_INCORE));
-+ mutex_unlock (&diskfs_disk_pager->interlock);
-+ if (is_incore)
-+ {
-+ mutex_unlock (&disk_cache_lock);
-+ printf ("INCORE\n");
-+ return disk_cache_block_ref (block); /* tail recursion */
-+ }
-+
-+#endif
-+
-+ /* Re-associate. */
-+ if (disk_cache_info[index].block != DC_NO_BLOCK)
-+ /* Remove old association. */
-+ hurd_ihash_remove (disk_cache_bptr, disk_cache_info[index].block);
-+ /* New association. */
-+ if (hurd_ihash_add (disk_cache_bptr, block, bptr))
-+ ext2_panic ("Couldn't hurd_ihash_add new disk block");
-+ assert (! (disk_cache_info[index].flags & DC_DONT_REUSE & ~DC_UNTOUCHED));
-+ disk_cache_info[index].block = block;
-+ assert (! disk_cache_info[index].ref_count);
-+ disk_cache_info[index].ref_count = 1;
-+
-+ /* All data structures are set up. */
-+ mutex_unlock (&disk_cache_lock);
-+
-+ /* Try to read page. */
-+ *(volatile char *) bptr;
-+
-+ /* Check if it's actually read. */
-+ mutex_lock (&disk_cache_lock);
-+ if (disk_cache_info[index].flags & DC_UNTOUCHED)
-+ /* It's not read. */
-+ {
-+ /* Remove newly created association. */
-+ hurd_ihash_remove (disk_cache_bptr, block);
-+ disk_cache_info[index].block = DC_NO_BLOCK;
-+ disk_cache_info[index].flags &=~ DC_UNTOUCHED;
-+ disk_cache_info[index].ref_count = 0;
-+ mutex_unlock (&disk_cache_lock);
-+
-+ /* Prepare next time association of this page to succeed. */
-+ pager_flush_some (diskfs_disk_pager, bptr - disk_cache,
-+ vm_page_size, 0);
-+
-+#if 0
-+ printf ("Re-association failed.\n");
-+#endif
-+
-+ /* Try again. */
-+ return disk_cache_block_ref (block); /* tail recursion */
-+ }
-+ mutex_unlock (&disk_cache_lock);
-+
-+ /* Re-association was successful. */
-+ condition_broadcast (&disk_cache_reassociation);
-+
-+ ext2_debug ("(%u) = %p", block, bptr);
-+ return bptr;
-+}
-+
-+void
-+disk_cache_block_ref_ptr (void *ptr)
-+{
-+ int index;
-+
-+ mutex_lock (&disk_cache_lock);
-+ index = bptr_index (ptr);
-+ assert (disk_cache_info[index].ref_count >= 1);
-+ assert (disk_cache_info[index].ref_count + 1
-+ > disk_cache_info[index].ref_count);
-+ disk_cache_info[index].ref_count++;
-+ assert (! (disk_cache_info[index].flags & DC_UNTOUCHED));
-+ ext2_debug ("(%p) (ref_count = %d, flags = 0x%x)",
-+ ptr,
-+ disk_cache_info[index].ref_count,
-+ disk_cache_info[index].flags);
-+ mutex_unlock (&disk_cache_lock);
-+}
-+
-+void
-+disk_cache_block_deref (void *ptr)
-+{
-+ int index;
-+
-+ assert (disk_cache <= ptr && ptr <= disk_cache + disk_cache_size);
-+
-+ mutex_lock (&disk_cache_lock);
-+ index = bptr_index (ptr);
-+ ext2_debug ("(%p) (ref_count = %d, flags = 0x%x)",
-+ ptr,
-+ disk_cache_info[index].ref_count - 1,
-+ disk_cache_info[index].flags);
-+ assert (! (disk_cache_info[index].flags & DC_UNTOUCHED));
-+ assert (disk_cache_info[index].ref_count >= 1);
-+ disk_cache_info[index].ref_count--;
-+ mutex_unlock (&disk_cache_lock);
-+}
-+
-+/* Not used. */
-+int
-+disk_cache_block_is_ref (block_t block)
-+{
-+ int ref;
-+ void *ptr;
-+
-+ mutex_lock (&disk_cache_lock);
-+ ptr = hurd_ihash_find (disk_cache_bptr, block);
-+ if (! ptr)
-+ ref = 0;
-+ else /* XXX: Should check for DC_UNTOUCHED too. */
-+ ref = disk_cache_info[bptr_index (ptr)].ref_count;
-+ mutex_unlock (&disk_cache_lock);
-+
-+ return ref;
-+}
-+
- /* Create the DISK pager. */
- void
- create_disk_pager (void)
-@@ -774,8 +1197,12 @@
- ext2_panic ("can't create disk pager: %s", strerror (errno));
- upi->type = DISK;
- pager_bucket = ports_create_bucket ();
-- diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, store->size,
-- &disk_image);
-+ get_hypermetadata ();
-+ disk_cache_blocks = DISK_CACHE_BLOCKS;
-+ disk_cache_size = disk_cache_blocks << log2_block_size;
-+ diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 1,
-+ disk_cache_size, &disk_cache);
-+ disk_cache_init ();
- }
-
- /* Call this to create a FILE_DATA pager and return a send right.
-@@ -815,7 +1242,7 @@
- diskfs_nref_light (node);
- node->dn->pager =
- pager_create (upi, pager_bucket, MAY_CACHE,
-- MEMORY_OBJECT_COPY_DELAY);
-+ MEMORY_OBJECT_COPY_DELAY, 0);
- if (node->dn->pager == 0)
- {
- diskfs_nrele_light (node);
-Index: hurd-debian/ext2fs/pokel.c
-===================================================================
---- hurd-debian.orig/ext2fs/pokel.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/pokel.c 2012-07-10 01:39:22.000000000 +0000
-@@ -67,12 +67,27 @@
- vm_offset_t p_offs = pl->offset;
- vm_size_t p_end = p_offs + pl->length;
-
-- if (p_offs == offset && p_end == end)
-- break;
-+ if (p_offs <= offset && end <= p_end)
-+ {
-+ if (pokel->image == disk_cache)
-+ for (vm_offset_t i = offset; i < end; i += block_size)
-+ disk_cache_block_deref (disk_cache + i);
-+
-+ break;
-+ }
- else if (p_end >= offset && end >= p_offs)
- {
- pl->offset = offset < p_offs ? offset : p_offs;
- pl->length = (end > p_end ? end : p_end) - pl->offset;
-+
-+ if (pokel->image == disk_cache)
-+ {
-+ vm_offset_t i_begin = p_offs > offset ? p_offs : offset;
-+ vm_offset_t i_end = p_end < end ? p_end : end;
-+ for (vm_offset_t i = i_begin; i < i_end; i += block_size)
-+ disk_cache_block_deref (disk_cache + i);
-+ }
-+
- ext2_debug ("extended 0x%x[%ul] to 0x%x[%ul]",
- p_offs, p_end - p_offs, pl->offset, pl->length);
- break;
-@@ -106,18 +121,28 @@
- _pokel_exec (struct pokel *pokel, int sync, int wait)
- {
- struct poke *pl, *pokes, *last = NULL;
--
-+
- pthread_spin_lock (&pokel->lock);
- pokes = pokel->pokes;
- pokel->pokes = NULL;
- pthread_spin_unlock (&pokel->lock);
-
- for (pl = pokes; pl; last = pl, pl = pl->next)
-- if (sync)
-- {
-- ext2_debug ("syncing 0x%x[%ul]", pl->offset, pl->length);
-- pager_sync_some (pokel->pager, pl->offset, pl->length, wait);
-- }
-+ {
-+ if (sync)
-+ {
-+ ext2_debug ("syncing 0x%x[%ul]", pl->offset, pl->length);
-+ pager_sync_some (pokel->pager, pl->offset, pl->length, wait);
-+ }
-+
-+ if (pokel->image == disk_cache)
-+ {
-+ vm_offset_t begin = trunc_block (pl->offset);
-+ vm_offset_t end = round_block (pl->offset + pl->length);
-+ for (vm_offset_t i = begin; i != end; i += block_size)
-+ disk_cache_block_deref (pokel->image + i);
-+ }
-+ }
-
- if (last)
- {
-Index: hurd-debian/ext2fs/truncate.c
-===================================================================
---- hurd-debian.orig/ext2fs/truncate.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/ext2fs/truncate.c 2012-07-10 01:39:22.000000000 +0000
-@@ -124,7 +124,7 @@
- {
- unsigned index;
- int modified = 0, all_freed = 1;
-- block_t *ind_bh = (block_t *)bptr (*p);
-+ block_t *ind_bh = (block_t *)disk_cache_block_ref (*p);
- unsigned first = end < offset ? 0 : end - offset;
-
- for (index = first; index < addr_per_block; index++)
-@@ -139,11 +139,16 @@
-
- if (first == 0 && all_freed)
- {
-- pager_flush_some (diskfs_disk_pager, boffs (*p), block_size, 1);
-+ pager_flush_some (diskfs_disk_pager,
-+ bptr_index (ind_bh) << log2_block_size,
-+ block_size, 1);
- free_block_run_free_ptr (fbr, p);
-+ disk_cache_block_deref (ind_bh);
- }
- else if (modified)
- record_indir_poke (node, ind_bh);
-+ else
-+ disk_cache_block_deref (ind_bh);
- }
- }
-
-@@ -218,7 +223,7 @@
- /* Flush all the data past the new size from the kernel. Also force any
- delayed copies of this data to take place immediately. (We are implicitly
- changing the data to zeros and doing it without the kernel's immediate
-- knowledge; accordingl we must help out the kernel thusly.) */
-+ knowledge; accordingly we must help out the kernel thusly.) */
- static void
- force_delayed_copies (struct node *node, off_t length)
- {
-Index: hurd-debian/fatfs/pager.c
-===================================================================
---- hurd-debian.orig/fatfs/pager.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/fatfs/pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -596,6 +596,13 @@
- return 0;
- }
-
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page)
-+{
-+ assert (!"unrequested notification on eviction");
-+}
-+
- /* Grow the disk allocated to locked node NODE to be at least SIZE
- bytes, and set NODE->allocsize to the actual allocated size. (If
- the allocated size is already SIZE bytes, do nothing.) CRED
-@@ -752,7 +759,7 @@
- struct user_pager_info *upi = malloc (sizeof (struct user_pager_info));
- upi->type = FAT;
- pager_bucket = ports_create_bucket ();
-- diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE,
-+ diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 0,
- bytes_per_sector * sectors_per_fat,
- &fat_image);
- }
-@@ -794,7 +801,7 @@
- diskfs_nref_light (node);
- node->dn->pager =
- pager_create (upi, pager_bucket, MAY_CACHE,
-- MEMORY_OBJECT_COPY_DELAY);
-+ MEMORY_OBJECT_COPY_DELAY, 0);
- if (node->dn->pager == 0)
- {
- diskfs_nrele_light (node);
-Index: hurd-debian/isofs/pager.c
-===================================================================
---- hurd-debian.orig/isofs/pager.c 2012-07-10 01:33:10.000000000 +0000
-+++ hurd-debian/isofs/pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -94,6 +94,13 @@
- return EROFS;
- }
-
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page)
-+{
-+ assert (!"unrequested notification on eviction");
-+}
-+
- /* Tell how big the file is. */
- error_t
- pager_report_extent (struct user_pager_info *pager,
-@@ -137,7 +144,7 @@
- upi->type = DISK;
- upi->np = 0;
- pager_bucket = ports_create_bucket ();
-- diskfs_start_disk_pager (upi, pager_bucket, 1, store->size, &disk_image);
-+ diskfs_start_disk_pager (upi, pager_bucket, 1, 0, store->size, &disk_image);
- upi->p = diskfs_disk_pager;
- }
-
-@@ -168,7 +175,8 @@
- upi->type = FILE_DATA;
- upi->np = np;
- diskfs_nref_light (np);
-- upi->p = pager_create (upi, pager_bucket, 1, MEMORY_OBJECT_COPY_DELAY);
-+ upi->p = pager_create (upi, pager_bucket, 1,
-+ MEMORY_OBJECT_COPY_DELAY, 0);
- if (upi->p == 0)
- {
- diskfs_nrele_light (np);
-Index: hurd-debian/libdiskfs/disk-pager.c
-===================================================================
---- hurd-debian.orig/libdiskfs/disk-pager.c 2012-07-10 01:33:11.000000000 +0000
-+++ hurd-debian/libdiskfs/disk-pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -46,7 +46,8 @@
-
- void
- diskfs_start_disk_pager (struct user_pager_info *upi,
-- struct port_bucket *pager_bucket, int may_cache,
-+ struct port_bucket *pager_bucket,
-+ int may_cache, int notify_on_evict,
- size_t size, void **image)
- {
- pthread_t thread;
-@@ -68,7 +69,8 @@
-
- /* Create the pager. */
- diskfs_disk_pager = pager_create (upi, pager_bucket,
-- may_cache, MEMORY_OBJECT_COPY_NONE);
-+ may_cache, MEMORY_OBJECT_COPY_NONE,
-+ notify_on_evict);
- assert (diskfs_disk_pager);
-
- /* Get a port to the disk pager. */
-Index: hurd-debian/libdiskfs/diskfs-pager.h
-===================================================================
---- hurd-debian.orig/libdiskfs/diskfs-pager.h 2012-07-10 01:33:11.000000000 +0000
-+++ hurd-debian/libdiskfs/diskfs-pager.h 2012-07-10 01:39:22.000000000 +0000
-@@ -33,7 +33,8 @@
- mapped is returned in IMAGE. INFO, PAGER_BUCKET, & MAY_CACHE are passed
- to `pager_create'. */
- extern void diskfs_start_disk_pager (struct user_pager_info *info,
-- struct port_bucket *pager_bucket, int may_cache,
-+ struct port_bucket *pager_bucket,
-+ int may_cache, int notify_on_evict,
- size_t size, void **image);
-
- extern struct pager *diskfs_disk_pager;
-Index: hurd-debian/libpager/data-request.c
-===================================================================
---- hurd-debian.orig/libpager/data-request.c 2012-11-26 00:23:28.000000000 +0000
-+++ hurd-debian/libpager/data-request.c 2012-11-26 00:24:49.000000000 +0000
-@@ -40,11 +40,11 @@
- if (!p)
- return EOPNOTSUPP;
-
-- /* Acquire the right to meddle with the pagemap */
-+ /* Acquire the right to meddle with the pagemap. */
- pthread_mutex_lock (&p->interlock);
- _pager_wait_for_seqno (p, seqno);
-
-- /* sanity checks -- we don't do multi-page requests yet. */
-+ /* Sanity checks -- we don't do multi-page requests yet. */
- if (control != p->memobjcntl)
- {
- printf ("incg data request: wrong control port\n");
-@@ -119,7 +119,8 @@
- goto error_read;
-
- memory_object_data_supply (p->memobjcntl, offset, page, length, 1,
-- write_lock ? VM_PROT_WRITE : VM_PROT_NONE, 0,
-+ write_lock ? VM_PROT_WRITE : VM_PROT_NONE,
-+ p->notify_on_evict ? 1 : 0,
- MACH_PORT_NULL);
- pthread_mutex_lock (&p->interlock);
- _pager_mark_object_error (p, offset, length, 0);
-Index: hurd-debian/libpager/data-return.c
-===================================================================
---- hurd-debian.orig/libpager/data-return.c 2012-11-26 00:23:28.000000000 +0000
-+++ hurd-debian/libpager/data-return.c 2012-11-26 00:24:49.000000000 +0000
-@@ -39,6 +39,7 @@
- struct pager *p;
- short *pm_entries;
- int npages, i;
-+ char *notified;
- error_t *pagerrs;
- struct lock_request *lr;
- struct lock_list {struct lock_request *lr;
-@@ -71,9 +72,6 @@
- goto release_out;
- }
-
-- if (! dirty)
-- goto release_out;
--
- if (p->pager_state != NORMAL)
- {
- printf ("pager in wrong state for write\n");
-@@ -83,6 +81,11 @@
- npages = length / __vm_page_size;
- pagerrs = alloca (npages * sizeof (error_t));
-
-+ notified = alloca (npages * (sizeof *notified));
-+#ifndef NDEBUG
-+ memset (notified, -1, npages * (sizeof *notified));
-+#endif
-+
- _pager_block_termination (p); /* until we are done with the pagemap
- when the write completes. */
-
-@@ -90,6 +93,24 @@
-
- pm_entries = &p->pagemap[offset / __vm_page_size];
-
-+ if (! dirty)
-+ {
-+ munmap ((caddr_t) data, length);
-+ if (!kcopy) {
-+ /* Prepare notified array. */
-+ for (i = 0; i < npages; i++)
-+ notified[i] = (p->notify_on_evict
-+ && ! (pm_entries[i] & PM_PAGEINWAIT));
-+
-+ _pager_release_seqno (p, seqno);
-+ goto notify;
-+ }
-+ else {
-+ _pager_allow_termination (p);
-+ goto release_out;
-+ }
-+ }
-+
- /* Make sure there are no other in-progress writes for any of these
- pages before we begin. This imposes a little more serialization
- than we really have to require (because *all* future writes on
-@@ -120,10 +141,6 @@
- for (i = 0; i < npages; i++)
- pm_entries[i] |= PM_PAGINGOUT | PM_INIT;
-
-- if (!kcopy)
-- for (i = 0; i < npages; i++)
-- pm_entries[i] &= ~PM_INCORE;
--
- /* If this write occurs while a lock is pending, record
- it. We have to keep this list because a lock request
- might come in while we do the I/O; in that case there
-@@ -163,7 +180,10 @@
- for (i = 0; i < npages; i++)
- {
- if (omitdata & (1 << i))
-- continue;
-+ {
-+ notified[i] = 0;
-+ continue;
-+ }
-
- if (pm_entries[i] & PM_WRITEWAIT)
- wakeup = 1;
-@@ -179,14 +199,22 @@
- pm_entries[i] |= PM_INVALID;
-
- if (pm_entries[i] & PM_PAGEINWAIT)
-- memory_object_data_supply (p->memobjcntl,
-- offset + (vm_page_size * i),
-- data + (vm_page_size * i),
-- vm_page_size, 1,
-- VM_PROT_NONE, 0, MACH_PORT_NULL);
-+ {
-+ memory_object_data_supply (p->memobjcntl,
-+ offset + (vm_page_size * i),
-+ data + (vm_page_size * i),
-+ vm_page_size, 1,
-+ VM_PROT_NONE, 0, MACH_PORT_NULL);
-+ notified[i] = 0;
-+ }
- else
-- munmap ((caddr_t) (data + (vm_page_size * i)),
-- vm_page_size);
-+ {
-+ munmap ((caddr_t) (data + (vm_page_size * i)),
-+ vm_page_size);
-+ notified[i] = (! kcopy && p->notify_on_evict);
-+ if (! kcopy)
-+ pm_entries[i] &= ~PM_INCORE;
-+ }
-
- pm_entries[i] &= ~(PM_PAGINGOUT | PM_PAGEINWAIT | PM_WRITEWAIT);
- }
-@@ -198,10 +226,29 @@
- if (wakeup)
- pthread_cond_broadcast (&p->wakeup);
-
-+ notify:
- _pager_allow_termination (p);
--
- pthread_mutex_unlock (&p->interlock);
-
-+ for (i = 0; i < npages; i++)
-+ {
-+ assert (notified[i] == 0 || notified[i] == 1);
-+ if (notified[i])
-+ {
-+ short *pm_entry = &pm_entries[i];
-+
-+ /* Do notify user. */
-+ pager_notify_evict (p->upi, offset + (i * vm_page_size));
-+
-+ /* Clear any error that is left. Notification on eviction
-+ is used only to change association of page, so any
-+ error may no longer be valid. */
-+ mutex_lock (&p->interlock);
-+ *pm_entry = SET_PM_ERROR (SET_PM_NEXTERROR (*pm_entry, 0), 0);
-+ mutex_unlock (&p->interlock);
-+ }
-+ }
-+
- ports_port_deref (p);
- return 0;
-
-Index: hurd-debian/libpager/pager-create.c
-===================================================================
---- hurd-debian.orig/libpager/pager-create.c 2012-07-10 01:33:11.000000000 +0000
-+++ hurd-debian/libpager/pager-create.c 2012-07-10 01:39:22.000000000 +0000
-@@ -22,7 +22,8 @@
- pager_create (struct user_pager_info *upi,
- struct port_bucket *bucket,
- boolean_t may_cache,
-- memory_object_copy_strategy_t copy_strategy)
-+ memory_object_copy_strategy_t copy_strategy,
-+ boolean_t notify_on_evict)
- {
- struct pager *p;
-
-@@ -38,6 +39,7 @@
- p->attribute_requests = 0;
- p->may_cache = may_cache;
- p->copy_strategy = copy_strategy;
-+ p->notify_on_evict = notify_on_evict;
- p->memobjcntl = MACH_PORT_NULL;
- p->memobjname = MACH_PORT_NULL;
- p->seqno = -1;
-Index: hurd-debian/libpager/pager.h
-===================================================================
---- hurd-debian.orig/libpager/pager.h 2012-07-10 01:33:11.000000000 +0000
-+++ hurd-debian/libpager/pager.h 2012-07-10 01:39:22.000000000 +0000
-@@ -32,18 +32,21 @@
- mach_msg_header_t *outp);
-
- /* Create a new pager. The pager will have a port created for it
-- (using libports, in BUCKET) and will be immediately ready
-- to receive requests. U_PAGER will be provided to later calls to
-+ (using libports, in BUCKET) and will be immediately ready to
-+ receive requests. U_PAGER will be provided to later calls to
- pager_find_address. The pager will have one user reference
- created. MAY_CACHE and COPY_STRATEGY are the original values of
-- those attributes as for memory_object_ready. Users may create
-- references to pagers by use of the relevant ports library
-- functions. On errors, return null and set errno. */
-+ those attributes as for memory_object_ready. If NOTIFY_ON_EVICT is
-+ non-zero, pager_notify_evict user callback will be called when page
-+ is evicted. Users may create references to pagers by use of the
-+ relevant ports library functions. On errors, return null and set
-+ errno. */
- struct pager *
- pager_create (struct user_pager_info *u_pager,
- struct port_bucket *bucket,
- boolean_t may_cache,
-- memory_object_copy_strategy_t copy_strategy);
-+ memory_object_copy_strategy_t copy_strategy,
-+ boolean_t notify_on_evict);
-
- /* Return the user_pager_info struct associated with a pager. */
- struct user_pager_info *
-@@ -110,7 +113,7 @@
- /* Change the attributes of the memory object underlying pager PAGER.
- Args MAY_CACHE and COPY_STRATEGY are as for
- memory_object_change_atributes. Wait for the kernel to report completion
-- off WAIT is set.*/
-+ iff WAIT is set. */
- void
- pager_change_attributes (struct pager *pager,
- boolean_t may_cache,
-@@ -172,6 +175,18 @@
- pager_unlock_page (struct user_pager_info *pager,
- vm_offset_t address);
-
-+/* The user must define this function. It is used when you want be
-+ able to change association of pages to backing store. To use it,
-+ pass non-zero value in NOTIFY_ON_EVICT when pager is created with
-+ pager_create. You can change association of page only when
-+ pager_notify_evict has been called and you haven't touched page
-+ content after that. Note there is a possibility that a page is
-+ evicted, but user is not notified about that. The user should be
-+ able to handle this case. */
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page);
-+
- /* The user must define this function. It should report back (in
- *OFFSET and *SIZE the minimum valid address the pager will accept
- and the size of the object. */
-Index: hurd-debian/libpager/priv.h
-===================================================================
---- hurd-debian.orig/libpager/priv.h 2012-07-10 01:33:11.000000000 +0000
-+++ hurd-debian/libpager/priv.h 2012-07-10 01:39:22.000000000 +0000
-@@ -48,6 +48,7 @@
-
- boolean_t may_cache;
- memory_object_copy_strategy_t copy_strategy;
-+ boolean_t notify_on_evict;
-
- /* Interface ports */
- memory_object_control_t memobjcntl;
-Index: hurd-debian/storeio/pager.c
-===================================================================
---- hurd-debian.orig/storeio/pager.c 2012-07-10 01:33:12.000000000 +0000
-+++ hurd-debian/storeio/pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -109,6 +109,13 @@
- return 0;
- }
-
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page)
-+{
-+ assert (!"unrequested notification on eviction");
-+}
-+
- /* The user must define this function. It should report back (in
- *OFFSET and *SIZE the minimum valid address the pager will accept
- and the size of the object. */
-@@ -232,7 +239,7 @@
- {
- dev->pager =
- pager_create ((struct user_pager_info *)dev, pager_port_bucket,
-- 1, MEMORY_OBJECT_COPY_DELAY);
-+ 1, MEMORY_OBJECT_COPY_DELAY, 0);
- if (dev->pager == NULL)
- {
- pthread_mutex_unlock (&dev->pager_lock);
-Index: hurd-debian/tmpfs/pager-stubs.c
-===================================================================
---- hurd-debian.orig/tmpfs/pager-stubs.c 2012-11-26 00:23:28.000000000 +0000
-+++ hurd-debian/tmpfs/pager-stubs.c 2012-11-26 00:24:49.000000000 +0000
-@@ -57,6 +57,14 @@
- return EIEIO;
- }
-
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page)
-+{
-+ abort();
-+}
-+
-+
- /* The user must define this function. It should report back (in
- *OFFSET and *SIZE the minimum valid address the pager will accept
- and the size of the object. */
-Index: hurd-debian/ufs/pager.c
-===================================================================
---- hurd-debian.orig/ufs/pager.c 2012-07-10 01:33:12.000000000 +0000
-+++ hurd-debian/ufs/pager.c 2012-07-10 01:39:22.000000000 +0000
-@@ -425,6 +425,13 @@
- return err;
- }
-
-+void
-+pager_notify_evict (struct user_pager_info *pager,
-+ vm_offset_t page)
-+{
-+ assert (!"unrequested notification on eviction");
-+}
-+
- /* Implement the pager_report_extent callback from the pager library. See
- <hurd/pager.h> for the interface description. */
- inline error_t
-@@ -477,7 +484,7 @@
- upi->type = DISK;
- upi->np = 0;
- pager_bucket = ports_create_bucket ();
-- diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, store->size,
-+ diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 0, store->size,
- &disk_image);
- upi->p = diskfs_disk_pager;
- }
-@@ -570,7 +577,7 @@
- upi->unlocked_pagein_length = 0;
- diskfs_nref_light (np);
- upi->p = pager_create (upi, pager_bucket,
-- MAY_CACHE, MEMORY_OBJECT_COPY_DELAY);
-+ MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0);
- if (upi->p == 0)
- {
- diskfs_nrele_light (np);
diff --git a/debian/patches/ext2fs_large_stores_pthread.patch b/debian/patches/ext2fs_large_stores_pthread.patch
deleted file mode 100644
index 71f76a34..00000000
--- a/debian/patches/ext2fs_large_stores_pthread.patch
+++ /dev/null
@@ -1,344 +0,0 @@
-commit 93691ae1ae88c2d66d240b50e3ea5827f8a96c22
-Author: Richard Braun <rbraun@sceen.net>
-Date: Mon Sep 3 22:19:16 2012 +0200
-
- Move large storage patch to pthreads
-
-TODO: merge into ext2fs_large_stores.patch.
-
-Index: hurd-debian/ext2fs/ext2fs.h
-===================================================================
---- hurd-debian.orig/ext2fs/ext2fs.h 2012-11-26 00:24:49.000000000 +0000
-+++ hurd-debian/ext2fs/ext2fs.h 2012-11-26 00:24:58.000000000 +0000
-@@ -260,9 +260,9 @@
- /* Metadata about cached block. */
- extern struct disk_cache_info *disk_cache_info;
- /* Lock for these mappings */
--extern struct mutex disk_cache_lock;
-+extern pthread_mutex_t disk_cache_lock;
- /* Fired when a re-association is done. */
--extern struct condition disk_cache_reassociation;
-+extern pthread_cond_t disk_cache_reassociation;
-
- void *disk_cache_block_ref (block_t block);
- void disk_cache_block_ref_ptr (void *ptr);
-@@ -345,9 +345,9 @@
- boffs_ptr (off_t offset)
- {
- block_t block = boffs_block (offset);
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- char *ptr = hurd_ihash_find (disk_cache_bptr, block);
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- assert (ptr);
- ptr += offset % block_size;
- ext2_debug ("(%Ld) = %p", offset, ptr);
-@@ -361,12 +361,12 @@ bptr_offs (void *ptr)
- vm_offset_t mem_offset = (char *)ptr - (char *)disk_cache;
- off_t offset;
- assert (mem_offset < disk_cache_size);
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- offset = (off_t) disk_cache_info[boffs_block (mem_offset)].block
- << log2_block_size;
- assert (offset || mem_offset < block_size);
- offset += mem_offset % block_size;
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- ext2_debug ("(%p) = %Ld", ptr, offset);
- return offset;
- }
-diff --git a/ext2fs/pager.c b/ext2fs/pager.c
-index 2bec88d..67c9922 100644
---- a/ext2fs/pager.c
-+++ b/ext2fs/pager.c
-@@ -418,7 +418,7 @@ disk_pager_read_page (vm_offset_t page, void **buf, int *writelock)
- size_t length = vm_page_size, read = 0;
- store_offset_t offset = page, dev_end = store->size;
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- int index = offset >> log2_block_size;
- offset = ((store_offset_t) disk_cache_info[index].block << log2_block_size)
- + offset % block_size;
-@@ -430,7 +430,7 @@ disk_pager_read_page (vm_offset_t page, void **buf, int *writelock)
- = disk_cache_info[index].block ^ DISK_CACHE_LAST_READ_XOR;
- #endif
- ext2_debug ("(%Ld)", offset >> log2_block_size);
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- if (offset + vm_page_size > dev_end)
- length = dev_end - offset;
-@@ -454,7 +454,7 @@ disk_pager_write_page (vm_offset_t page, void *buf)
- size_t length = vm_page_size, amount;
- store_offset_t offset = page, dev_end = store->size;
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- int index = offset >> log2_block_size;
- assert (disk_cache_info[index].block != DC_NO_BLOCK);
- offset = ((store_offset_t) disk_cache_info[index].block << log2_block_size)
-@@ -465,7 +465,7 @@ disk_pager_write_page (vm_offset_t page, void *buf)
- assert (disk_cache_info[index].last_read
- == disk_cache_info[index].block);
- #endif
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- if (offset + vm_page_size > dev_end)
- length = dev_end - offset;
-@@ -526,9 +526,9 @@ disk_pager_notify_evict (vm_offset_t page)
-
- ext2_debug ("(block %u)", index);
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- disk_cache_info[index].flags &= ~DC_INCORE;
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- }
-
- /* Satisfy a pager read request for either the disk pager or file pager
-@@ -836,9 +836,9 @@
- /* Hint index for which cache block to reuse next. */
- int disk_cache_hint;
- /* Lock for these structures. */
--struct mutex disk_cache_lock;
-+pthread_mutex_t disk_cache_lock;
- /* Fired when a re-association is done. */
--struct condition disk_cache_reassociation;
-+pthread_cond_t disk_cache_reassociation;
-
- /* Finish mapping initialization. */
- static void
-@@ -848,8 +848,8 @@
- ext2_panic ("Block size %d != vm_page_size %d",
- block_size, vm_page_size);
-
-- mutex_init (&disk_cache_lock);
-- condition_init (&disk_cache_reassociation);
-+ pthread_mutex_init (&disk_cache_lock, NULL);
-+ pthread_cond_init (&disk_cache_reassociation, NULL);
-
- /* Allocate space for block num -> in-memory pointer mapping. */
- if (hurd_ihash_create (&disk_cache_bptr, HURD_IHASH_NO_LOCP))
-@@ -905,7 +905,7 @@
-
- /* Return unused pages that are in core. */
- int pending_begin = -1, pending_end = -1;
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- for (index = 0; index < disk_cache_blocks; index++)
- if (! (disk_cache_info[index].flags & (DC_DONT_REUSE & ~DC_INCORE))
- && ! disk_cache_info[index].ref_count)
-@@ -916,13 +916,13 @@ disk_cache_return_unused (void)
- /* Return previous region, if there is such, ... */
- if (pending_end >= 0)
- {
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- pager_return_some (diskfs_disk_pager,
- pending_begin * vm_page_size,
- (pending_end - pending_begin)
- * vm_page_size,
- 1);
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- }
- /* ... and start new region. */
- pending_begin = index;
-@@ -930,7 +930,7 @@ disk_cache_return_unused (void)
- pending_end = index + 1;
- }
-
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- /* Return last region, if there is such. */
- if (pending_end >= 0)
-@@ -958,7 +958,7 @@ disk_cache_block_ref (block_t block)
-
- ext2_debug ("(%u)", block);
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
-
- bptr = hurd_ihash_find (disk_cache_bptr, block);
- if (bptr)
-@@ -971,8 +971,8 @@
- if (disk_cache_info[index].flags & DC_UNTOUCHED)
- {
- /* Wait re-association to finish. */
-- condition_wait (&disk_cache_reassociation, &disk_cache_lock);
-- mutex_unlock (&disk_cache_lock);
-+ pthread_cond_wait (&disk_cache_reassociation, &disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- #if 0
- printf ("Re-association -- wait finished.\n");
-@@ -992,7 +992,7 @@
- disk_cache_info[index].ref_count,
- disk_cache_info[index].flags, bptr);
-
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- return bptr;
- }
-@@ -1030,7 +1030,7 @@ disk_cache_block_ref (block_t block)
- {
- ext2_debug ("flush %u -> %d", disk_cache_info[index].block, index);
-
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- disk_cache_return_unused ();
-
-@@ -1050,9 +1050,9 @@ disk_cache_block_ref (block_t block)
-
- #if 0 /* XXX: Let's see if this is needed at all. */
-
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- pager_return_some (diskfs_disk_pager, bptr - disk_cache, vm_page_size, 1);
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
-
- /* Has someone used our bptr? Has someone mapped requested block
- while we have unlocked disk_cache_lock? If so, environment has
-@@ -1060,7 +1060,7 @@ disk_cache_block_ref (block_t block)
- if ((! (disk_cache_info[index].flags & DC_UNTOUCHED))
- || hurd_ihash_find (disk_cache_bptr, block))
- {
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- return disk_cache_block_ref (block); /* tail recursion */
- }
-
-@@ -1068,15 +1068,15 @@ disk_cache_block_ref (block_t block)
-
- /* XXX: Use libpager internals. */
-
-- mutex_lock (&diskfs_disk_pager->interlock);
-+ pthread_mutex_lock (&diskfs_disk_pager->interlock);
- int page = (bptr - disk_cache) / vm_page_size;
- assert (page >= 0);
- int is_incore = (page < diskfs_disk_pager->pagemapsize
- && (diskfs_disk_pager->pagemap[page] & PM_INCORE));
-- mutex_unlock (&diskfs_disk_pager->interlock);
-+ pthread_mutex_unlock (&diskfs_disk_pager->interlock);
- if (is_incore)
- {
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- printf ("INCORE\n");
- return disk_cache_block_ref (block); /* tail recursion */
- }
-@@ -1096,13 +1096,13 @@ disk_cache_block_ref (block_t block)
- disk_cache_info[index].ref_count = 1;
-
- /* All data structures are set up. */
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- /* Try to read page. */
- *(volatile char *) bptr;
-
- /* Check if it's actually read. */
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- if (disk_cache_info[index].flags & DC_UNTOUCHED)
- /* It's not read. */
- {
-@@ -1111,7 +1111,7 @@ disk_cache_block_ref (block_t block)
- disk_cache_info[index].block = DC_NO_BLOCK;
- disk_cache_info[index].flags &=~ DC_UNTOUCHED;
- disk_cache_info[index].ref_count = 0;
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- /* Prepare next time association of this page to succeed. */
- pager_flush_some (diskfs_disk_pager, bptr - disk_cache,
-@@ -1124,10 +1124,10 @@ disk_cache_block_ref (block_t block)
- /* Try again. */
- return disk_cache_block_ref (block); /* tail recursion */
- }
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- /* Re-association was successful. */
-- condition_broadcast (&disk_cache_reassociation);
-+ pthread_cond_broadcast (&disk_cache_reassociation);
-
- ext2_debug ("(%u) = %p", block, bptr);
- return bptr;
-@@ -1139,7 +1139,7 @@
- {
- int index;
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- index = bptr_index (ptr);
- assert (disk_cache_info[index].ref_count >= 1);
- assert (disk_cache_info[index].ref_count + 1
-@@ -1149,7 +1149,7 @@ disk_cache_block_ref_ptr (void *ptr)
- ptr,
- disk_cache_info[index].ref_count,
- disk_cache_info[index].flags);
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- }
-
- void
-@@ -1159,7 +1159,7 @@ disk_cache_block_deref (void *ptr)
-
- assert (disk_cache <= ptr && ptr <= disk_cache + disk_cache_size);
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- index = bptr_index (ptr);
- ext2_debug ("(%p) (ref_count = %d, flags = 0x%x)",
- ptr,
-@@ -1168,7 +1168,7 @@ disk_cache_block_deref (void *ptr)
- assert (! (disk_cache_info[index].flags & DC_UNTOUCHED));
- assert (disk_cache_info[index].ref_count >= 1);
- disk_cache_info[index].ref_count--;
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
- }
-
- /* Not used. */
-@@ -1179,13 +1179,13 @@ disk_cache_block_is_ref (block_t block)
- int ref;
- void *ptr;
-
-- mutex_lock (&disk_cache_lock);
-+ pthread_mutex_lock (&disk_cache_lock);
- ptr = hurd_ihash_find (disk_cache_bptr, block);
- if (! ptr)
- ref = 0;
- else /* XXX: Should check for DC_UNTOUCHED too. */
- ref = disk_cache_info[bptr_index (ptr)].ref_count;
-- mutex_unlock (&disk_cache_lock);
-+ pthread_mutex_unlock (&disk_cache_lock);
-
- return ref;
- }
-diff --git a/libpager/data-return.c b/libpager/data-return.c
-index 24533e7..0d71db7 100644
---- a/libpager/data-return.c
-+++ b/libpager/data-return.c
-@@ -243,9 +243,9 @@ _pager_do_write_request (mach_port_t object,
- /* Clear any error that is left. Notification on eviction
- is used only to change association of page, so any
- error may no longer be valid. */
-- mutex_lock (&p->interlock);
-+ pthread_mutex_lock (&p->interlock);
- *pm_entry = SET_PM_ERROR (SET_PM_NEXTERROR (*pm_entry, 0), 0);
-- mutex_unlock (&p->interlock);
-+ pthread_mutex_unlock (&p->interlock);
- }
- }
-
diff --git a/debian/patches/mount-f.patch b/debian/patches/mount-f.patch
deleted file mode 100644
index aabc47b7..00000000
--- a/debian/patches/mount-f.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-Add -f and --fake arguments. This makes our mount more compatible with
-Linux mount.
-
-* utils/mount.c (argp_opts): Add -f and --fake.
-(do_mount): Fake the translator startup if --fake is given.
----
- utils/mount.c | 29 ++++++++++++++++++++++++++++-
- 1 file changed, 28 insertions(+), 1 deletion(-)
-
-diff --git a/utils/mount.c b/utils/mount.c
-index f1d5750..f8928f1 100644
---- a/utils/mount.c
-+++ b/utils/mount.c
-@@ -24,6 +24,7 @@
- #include <error.h>
- #include <stdlib.h>
- #include <fcntl.h>
-+#include <unistd.h>
- #include <hurd/fsys.h>
- #include <hurd/fshelp.h>
- #include <hurd/paths.h>
-@@ -34,6 +35,7 @@
- static char *fstype = DEFAULT_FSTYPE;
- static char *device, *mountpoint;
- static int verbose;
-+static int fake;
- static char *options;
- static size_t options_len;
- static mach_msg_timeout_t timeout;
-@@ -55,6 +57,7 @@ static const struct argp_option argp_opts[] =
- {"remount", 0, 0, OPTION_ALIAS},
- {"verbose", 'v', 0, 0, "Give more detailed information"},
- {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
-+ {"fake", 'f', 0, 0, "Do not actually mount, just pretend"},
- {0, 0}
- };
-
-@@ -115,6 +118,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
- /* do nothing */
- break;
-
-+ case 'f':
-+ fake = 1;
-+ break;
-+
- case ARGP_KEY_ARG:
- if (mountpoint == 0) /* One arg: mountpoint */
- mountpoint = arg;
-@@ -312,7 +319,10 @@ do_mount (struct fs *fs, int remount)
- return 0;
- }
-
-- if (mounted != MACH_PORT_NULL)
-+ /* Do not fail if there is an active translator if --fake is
-+ given. This mimics Linux mount utility more closely which
-+ just looks into the mtab file. */
-+ if (mounted != MACH_PORT_NULL && !fake)
- {
- error (0, 0, "%s already mounted", fs->mntent.mnt_fsname);
- return EBUSY;
-@@ -342,6 +352,23 @@ do_mount (struct fs *fs, int remount)
-
- /* Now we have a translator command line argz in FSOPTS. */
-
-+ if (fake) {
-+ /* Fake the translator startup. */
-+ mach_port_t underlying;
-+ mach_msg_type_name_t underlying_type;
-+ err = open_node (O_READ, &underlying, &underlying_type, 0, NULL);
-+ if (err)
-+ error (1, errno, "cannot mount on %s", fs->mntent.mnt_dir);
-+
-+ mach_port_deallocate (mach_task_self (), underlying);
-+
-+ /* See if the translator is at least executable. */
-+ if (access(type->program, X_OK) == -1)
-+ error (1, errno, "can not execute %s", type->program);
-+
-+ return 0;
-+ }
-+
- explain ("settrans -a");
- err = fshelp_start_translator (open_node, NULL, fsopts,
- fsopts, fsopts_len, timeout,
---
-1.7.10.4
-
-
diff --git a/debian/patches/mount-ignore-mounted-all.patch b/debian/patches/mount-ignore-mounted-all.patch
deleted file mode 100644
index b3890d4a..00000000
--- a/debian/patches/mount-ignore-mounted-all.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-Linux' mount utility ignores mounted filesystems if mount --all is
-invoked. This patch makes our mount do the same.
-
-utils/mount.c (main): Ignore mounted filesystems if --all is given.
----
- utils/mount.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/utils/mount.c b/utils/mount.c
-index 73a7539..77b2138 100644
---- a/utils/mount.c
-+++ b/utils/mount.c
-@@ -631,6 +631,15 @@ main (int argc, char **argv)
-
- if (! match_options (&fs->mntent))
- continue;
-+
-+ fsys_t mounted;
-+ err = fs_fsys (fs, &mounted);
-+ if (err)
-+ error (0, err, "cannot determine if %s is already mounted",
-+ fs->mntent.mnt_fsname);
-+
-+ if (mounted != MACH_PORT_NULL)
-+ continue;
- }
- err |= do_mount (fs, remount);
- }
---
-1.7.10.4
-
-
diff --git a/debian/patches/mount-n.patch b/debian/patches/mount-n.patch
deleted file mode 100644
index 9b860877..00000000
--- a/debian/patches/mount-n.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-Add -n and --no-mtab arguments. As we do not write an mtab file, this
-is a trivial patch that just ignores this argument to be more
-compatible with Linux mount.
-
-* utils/mount.c (argp_opts): Add -n and --no-mtab.
-(parse_opt): Do nothing on 'n'.
----
- utils/mount.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/utils/mount.c b/utils/mount.c
-index 8b059c2..ea30f7a 100644
---- a/utils/mount.c
-+++ b/utils/mount.c
-@@ -54,6 +54,7 @@ static const struct argp_option argp_opts[] =
- {"update", 'u', 0, 0, "Flush any meta-data cached in core"},
- {"remount", 0, 0, OPTION_ALIAS},
- {"verbose", 'v', 0, 0, "Give more detailed information"},
-+ {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
- {0, 0}
- };
-
-@@ -110,6 +111,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
- }
- break;
-
-+ case 'n':
-+ /* do nothing */
-+ break;
-+
- case ARGP_KEY_ARG:
- if (mountpoint == 0) /* One arg: mountpoint */
- mountpoint = arg;
---
-1.7.10.4
-
-
diff --git a/debian/patches/mount-remount.patch b/debian/patches/mount-remount.patch
deleted file mode 100644
index 53eccb2b..00000000
--- a/debian/patches/mount-remount.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-This fixes mount -oremount when just given the mountpoint, e. g.:
-
- % mount -oremount,ro /tmp
-
-* util/mount.c (main): Add a one-argument form for remount.
----
- utils/mount.c | 29 +++++++++++++++++++++++------
- 1 file changed, 23 insertions(+), 6 deletions(-)
-
-diff --git a/utils/mount.c b/utils/mount.c
-index ea30f7a..f1d5750 100644
---- a/utils/mount.c
-+++ b/utils/mount.c
-@@ -526,6 +526,12 @@ main (int argc, char **argv)
-
- fstab = fstab_argp_create (&fstab_params, SEARCH_FMTS, sizeof SEARCH_FMTS);
-
-+ /* This is a convenient way of checking for any `remount' options. */
-+ remount = 0;
-+ err = argz_replace (&options, &options_len, "remount", "update", &remount);
-+ if (err)
-+ error (3, ENOMEM, "collecting mount options");
-+
- if (device) /* two-argument form */
- {
- struct mntent m =
-@@ -548,6 +554,23 @@ main (int argc, char **argv)
- if (err)
- error (2, err, "%s", mountpoint);
- }
-+ else if (mountpoint && remount) /* one-argument remount */
-+ {
-+ struct mntent m =
-+ {
-+ mnt_fsname: mountpoint, /* since we cannot know the device,
-+ using mountpoint here leads to more
-+ helpful error messages */
-+ mnt_dir: mountpoint,
-+ mnt_type: fstype,
-+ mnt_opts: 0,
-+ mnt_freq: 0, mnt_passno: 0
-+ };
-+
-+ err = fstab_add_mntent (fstab, &m, &fs);
-+ if (err)
-+ error (2, err, "%s", mountpoint);
-+ }
- else if (mountpoint) /* one-argument form */
- {
- fs = fstab_find (fstab, mountpoint);
-@@ -557,12 +580,6 @@ main (int argc, char **argv)
- else
- fs = 0;
-
-- /* This is a convenient way of checking for any `remount' options. */
-- remount = 0;
-- err = argz_replace (&options, &options_len, "remount", "update", &remount);
-- if (err)
-- error (3, ENOMEM, "collecting mount options");
--
- if (fs != 0)
- err = do_mount (fs, remount);
- else
---
-1.7.10.4
-
-
diff --git a/debian/patches/mount-t-auto.patch b/debian/patches/mount-t-auto.patch
deleted file mode 100644
index 5f800f41..00000000
--- a/debian/patches/mount-t-auto.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-Use libblkid to detect the filesystem type if "auto" is given as
-type. Remove the translator localization from main, this is also done
-in do_mount and any errors are propagated properly. This way "auto" is
-handled correctly if given on the command line or used as filesystem
-type in the fstab.
-
-* utils/mount.c (DEFAULT_FSTYPE): Use "auto" as default type.
-(do_mount): Detect type using libblkid.
-(main): Drop translator localization.
----
- utils/Makefile | 1 +
- utils/mount.c | 27 +++++++++++++++++++--------
- 2 files changed, 20 insertions(+), 8 deletions(-)
-
-diff --git a/utils/Makefile b/utils/Makefile
-index 6975fb5..207c904 100644
---- a/utils/Makefile
-+++ b/utils/Makefile
-@@ -37,6 +37,7 @@ LDLIBS += -lpthread
- login-LDLIBS = -lutil $(LIBCRYPT)
- addauth-LDLIBS = $(LIBCRYPT)
- setauth-LDLIBS = $(LIBCRYPT)
-+mount-LDLIBS = -lblkid
-
- INSTALL-login-ops = -o root -m 4755
- INSTALL-ids-ops = -o root -m 4755
-diff --git a/utils/mount.c b/utils/mount.c
-index 77b2138..5863f96 100644
---- a/utils/mount.c
-+++ b/utils/mount.c
-@@ -28,11 +28,12 @@
- #include <hurd/fsys.h>
- #include <hurd/fshelp.h>
- #include <hurd/paths.h>
-+#include <blkid/blkid.h>
-
- #include "match-options.h"
-
- #define SEARCH_FMTS _HURD "%sfs\0" _HURD "%s"
--#define DEFAULT_FSTYPE "ext2"
-+#define DEFAULT_FSTYPE "auto"
-
- static char *fstype = DEFAULT_FSTYPE;
- static char *device, *mountpoint;
-@@ -338,6 +339,23 @@ do_mount (struct fs *fs, int remount)
- return EBUSY;
- }
-
-+ if (strcmp (fs->mntent.mnt_type, "auto") == 0)
-+ {
-+ char *type =
-+ blkid_get_tag_value (NULL, "TYPE", fs->mntent.mnt_fsname);
-+ if (! type)
-+ {
-+ error (0, 0, "failed to detect file system type");
-+ return EFTYPE;
-+ }
-+ else
-+ {
-+ fs->mntent.mnt_type = strdup (type);
-+ if (! fs->mntent.mnt_type)
-+ error (3, ENOMEM, "failed to allocate memory");
-+ }
-+ }
-+
- err = fs_type (fs, &type);
- if (err)
- {
-@@ -579,13 +597,6 @@ main (int argc, char **argv)
- mnt_opts: 0,
- mnt_freq: 0, mnt_passno: 0
- };
-- struct fstype *fst;
--
-- err = fstypes_get (fstab->types, fstype, &fst);
-- if (err)
-- error (106, err, "cannot initialize type %s", fstype);
-- if (fst->program == 0)
-- error (2, 0, "filesystem type %s not recognized", fstype);
-
- err = fstab_add_mntent (fstab, &m, &fs);
- if (err)
---
-1.7.10.4
-
-
diff --git a/debian/patches/mount-test-opts.patch b/debian/patches/mount-test-opts.patch
index e694b69f..d2e0f0e1 100644
--- a/debian/patches/mount-test-opts.patch
+++ b/debian/patches/mount-test-opts.patch
@@ -1,214 +1,13 @@
---test-opts in combination with --all mounts only those filesystems
-with options matching the given set of options.
-
-Note that the semantic of the inverting "no" prefix differs from
---types: While --types=nonfs,ufs means neither nfs nor ufs,
---test-opts=nofoo,bar means not foo, but bar.
-
-* utils/match-options.h: New file.
-* utils/match-options.c: Likewise.
-(test_opts): New variable.
-(test_opts_len): Likewise.
-(match_options): New function.
-* utils/mount.c (parse_opt): Handle -O, --test-opts.
-(main): Use match_options as filter.
----
- utils/Makefile | 5 ++--
- utils/match-options.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
- utils/match-options.h | 33 ++++++++++++++++++++++++
- utils/mount.c | 19 ++++++++++++--
- 4 files changed, 121 insertions(+), 4 deletions(-)
- create mode 100644 utils/match-options.c
- create mode 100644 utils/match-options.h
-
diff --git a/utils/Makefile b/utils/Makefile
index e3bed0b..6975fb5 100644
--- a/utils/Makefile
+++ b/utils/Makefile
-@@ -28,7 +28,8 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
- uptime.sh psout.c ids.c vmstat.c portinfo.c devprobe.c vminfo.c \
+@@ -28,7 +28,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \
unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \
-- rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh
-+ rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \
-+ match-options.c
+ rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \
+- nullauth.c
++ nullauth.c match-options.c
OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
-@@ -72,7 +73,7 @@ fakeauth-CPPFLAGS = -I$(srcdir)/../auth
- authServer-CPPFLAGS = -I$(srcdir)/../auth
- auth_requestUser-CPPFLAGS = -I$(srcdir)/../auth
-
--mount: ../sutils/fstab.o ../sutils/clookup.o \
-+mount: ../sutils/fstab.o ../sutils/clookup.o match-options.o \
- $(foreach L,fshelp ports,../lib$L/lib$L.a)
- ../sutils/fstab.o ../sutils/clookup.o: FORCE
- $(MAKE) -C $(@D) $(@F)
-diff --git a/utils/match-options.c b/utils/match-options.c
-new file mode 100644
-index 0000000..11fc9dc
---- /dev/null
-+++ b/utils/match-options.c
-@@ -0,0 +1,68 @@
-+/* Common functionality for the --test-opts flag of mount and umount.
-+
-+ Copyright (C) 2013 Free Software Foundation, Inc.
-+ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
-+
-+ 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 this program; if not, write to the Free Software
-+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-+
-+#include <argz.h>
-+#include <error.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "match-options.h"
-+
-+char *test_opts;
-+size_t test_opts_len;
-+
-+int
-+match_options (struct mntent *mntent)
-+{
-+ char *opts;
-+ size_t opts_len;
-+
-+ error_t err = argz_create_sep (mntent->mnt_opts, ',', &opts, &opts_len);
-+ if (err)
-+ error (3, err, "parsing mount options failed");
-+
-+ for (char *test = test_opts;
-+ test; test = argz_next (test_opts, test_opts_len, test))
-+ {
-+ char *needle = test;
-+ int inverse = strncmp("no", needle, 2) == 0;
-+ if (inverse)
-+ needle += 2;
-+
-+ int match = 0;
-+ for (char *opt = opts; opt; opt = argz_next (opts, opts_len, opt))
-+ {
-+ if (strcmp (opt, needle) == 0) {
-+ if (inverse)
-+ return 0; /* foo in opts, nofoo in test_opts. */
-+
-+ /* foo in opts, foo in test_opts, record match. */
-+ match = 1;
-+ }
-+ }
-+
-+ if (! inverse && ! match)
-+ return 0; /* No foo in opts, but foo in test_opts. */
-+ }
-+
-+ /* If no conflicting test_opt was encountered, return success. */
-+ return 1;
-+}
-diff --git a/utils/match-options.h b/utils/match-options.h
-new file mode 100644
-index 0000000..ea7ae70
---- /dev/null
-+++ b/utils/match-options.h
-@@ -0,0 +1,33 @@
-+/* Common functionality for the --test-opts flag of mount and umount.
-+
-+ Copyright (C) 2013 Free Software Foundation, Inc.
-+ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
-+
-+ 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 this program; if not, write to the Free Software
-+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-+
-+#include <mntent.h>
-+
-+extern char *test_opts;
-+extern size_t test_opts_len;
-+
-+/* Check whether the given mount entry matches the given set of
-+ options.
-+
-+ Returns 0 if foo is in the options vector but nofoo is in test_opts.
-+ Returns 0 if foo is in test_opts but foo is not in the options vector. */
-+int
-+match_options (struct mntent *mntent);
-diff --git a/utils/mount.c b/utils/mount.c
-index f8928f1..73a7539 100644
---- a/utils/mount.c
-+++ b/utils/mount.c
-@@ -29,6 +29,8 @@
- #include <hurd/fshelp.h>
- #include <hurd/paths.h>
-
-+#include "match-options.h"
-+
- #define SEARCH_FMTS _HURD "%sfs\0" _HURD "%s"
- #define DEFAULT_FSTYPE "ext2"
-
-@@ -57,6 +59,8 @@ static const struct argp_option argp_opts[] =
- {"remount", 0, 0, OPTION_ALIAS},
- {"verbose", 'v', 0, 0, "Give more detailed information"},
- {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
-+ {"test-opts", 'O', "OPTIONS", 0,
-+ "Only mount fstab entries matching the given set of options"},
- {"fake", 'f', 0, 0, "Do not actually mount, just pretend"},
- {0, 0}
- };
-@@ -122,6 +126,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
- fake = 1;
- break;
-
-+ case 'O':
-+ err = argz_create_sep (arg, ',', &test_opts, &test_opts_len);
-+ if (err)
-+ argp_failure (state, 100, ENOMEM, "%s", arg);
-+ break;
-+
- case ARGP_KEY_ARG:
- if (mountpoint == 0) /* One arg: mountpoint */
- mountpoint = arg;
-@@ -615,8 +625,13 @@ main (int argc, char **argv)
- case mount:
- for (fs = fstab->entries; fs; fs = fs->next)
- {
-- if (fstab_params.do_all && hasmntopt (&fs->mntent, MNTOPT_NOAUTO))
-- continue;
-+ if (fstab_params.do_all) {
-+ if (hasmntopt (&fs->mntent, MNTOPT_NOAUTO))
-+ continue;
-+
-+ if (! match_options (&fs->mntent))
-+ continue;
-+ }
- err |= do_mount (fs, remount);
- }
- break;
---
-1.7.10.4
-
-
diff --git a/debian/patches/procfs-default.patch b/debian/patches/procfs-default.patch
deleted file mode 100644
index 023ab9d5..00000000
--- a/debian/patches/procfs-default.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-Define a macro for the default value of each command line
-parameter. This allows one to generate a minimal response to
-fsys_get_options requests.
-
-* procfs/main.c: New macro definitions for default values.
----
- procfs/main.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/procfs/main.c b/procfs/main.c
-index ba74e87..3e53307 100644
---- a/procfs/main.c
-+++ b/procfs/main.c
-@@ -37,6 +37,13 @@ pid_t opt_fake_self;
- #define NOEXEC_KEY -2 /* Likewise. */
- #define NOSUID_KEY -3 /* Likewise. */
-
-+/* Default values */
-+#define OPT_CLK_TCK sysconf(_SC_CLK_TCK)
-+#define OPT_STAT_MODE 0400
-+#define OPT_FAKE_SELF -1
-+#define OPT_KERNEL_PID 2
-+#define OPT_ANON_OWNER 0
-+
- static error_t
- argp_parser (int key, char *arg, struct argp_state *state)
- {
-@@ -211,11 +218,11 @@ int main (int argc, char **argv)
- mach_port_t bootstrap;
- error_t err;
-
-- opt_clk_tck = sysconf(_SC_CLK_TCK);
-- opt_stat_mode = 0400;
-- opt_fake_self = -1;
-- opt_kernel_pid = 2;
-- opt_anon_owner = 0;
-+ opt_clk_tck = OPT_CLK_TCK;
-+ opt_stat_mode = OPT_STAT_MODE;
-+ opt_fake_self = OPT_FAKE_SELF;
-+ opt_kernel_pid = OPT_KERNEL_PID;
-+ opt_anon_owner = OPT_ANON_OWNER;
- err = argp_parse (&argp, argc, argv, 0, 0, 0);
- if (err)
- error (1, err, "Could not parse command line");
---
-1.7.10.4
-
-
diff --git a/debian/patches/procfs-get-options.patch b/debian/patches/procfs-get-options.patch
deleted file mode 100644
index 99104177..00000000
--- a/debian/patches/procfs-get-options.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-Implement our own netfs_append_args function that provides the
-appropriate command line flags if the current values differ from the
-default values.
-
-* procfs/main.c (netfs_append_args): New function.
----
- procfs/main.c | 42 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 42 insertions(+)
-
-diff --git a/procfs/main.c b/procfs/main.c
-index 3e53307..bcf9590 100644
---- a/procfs/main.c
-+++ b/procfs/main.c
-@@ -22,6 +22,7 @@
- #include <unistd.h>
- #include <error.h>
- #include <argp.h>
-+#include <argz.h>
- #include <hurd/netfs.h>
- #include <ps.h>
- #include "procfs.h"
-@@ -193,6 +194,47 @@ struct argp netfs_runtime_argp_ = {
- /* Used by netfs_set_options to handle runtime option parsing. */
- struct argp *netfs_runtime_argp = &netfs_runtime_argp_;
-
-+/* Return an argz string describing the current options. Fill *ARGZ
-+ with a pointer to newly malloced storage holding the list and *LEN
-+ to the length of that storage. */
-+error_t
-+netfs_append_args (char **argz, size_t *argz_len)
-+{
-+ char buf[80];
-+ error_t err = 0;
-+
-+#define FOPT(opt, default, fmt, args...) \
-+ do { \
-+ if (! err && opt != default) \
-+ { \
-+ snprintf (buf, sizeof buf, fmt, ## args); \
-+ err = argz_add (argz, argz_len, buf); \
-+ } \
-+ } while (0)
-+
-+ FOPT (opt_clk_tck, OPT_CLK_TCK,
-+ "--clk-tck=%d", opt_clk_tck);
-+
-+ FOPT (opt_stat_mode, OPT_STAT_MODE,
-+ "--stat-mode=%o", opt_stat_mode);
-+
-+ FOPT (opt_fake_self, OPT_FAKE_SELF,
-+ "--fake-self=%d", opt_fake_self);
-+
-+ FOPT (opt_anon_owner, OPT_ANON_OWNER,
-+ "--anonymous-owner=%d", opt_anon_owner);
-+
-+ FOPT (opt_kernel_pid, OPT_KERNEL_PID,
-+ "--kernel-process=%d", opt_kernel_pid);
-+
-+#undef FOPT
-+
-+ if (! err)
-+ err = netfs_append_std_options (argz, argz_len);
-+
-+ return err;
-+}
-+
- error_t
- root_make_node (struct ps_context *pc, struct node **np)
- {
---
-1.7.10.4
-
-
diff --git a/debian/patches/procfs-update.patch b/debian/patches/procfs-update.patch
deleted file mode 100644
index 67b415ca..00000000
--- a/debian/patches/procfs-update.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-Split the argument handling into a common part and one for
-fsys_update_options. Handle the --update parameter; for procfs this is
-a no-op.
-
-* procfs/main.c (common_options): New variable.
-(runtime_argp_parser): Handle --update.
-(startup_argp): New variable.
-(netfs_runtime_argp_): New variable.
----
- procfs/main.c | 93 ++++++++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 65 insertions(+), 28 deletions(-)
-
-diff --git a/procfs/main.c b/procfs/main.c
-index 1b19c01..ba74e87 100644
---- a/procfs/main.c
-+++ b/procfs/main.c
-@@ -109,51 +109,88 @@ argp_parser (int key, char *arg, struct argp_state *state)
- return 0;
- }
-
-+struct argp_option common_options[] = {
-+ { "clk-tck", 'h', "HZ", 0,
-+ "Unit used for the values expressed in system clock ticks "
-+ "(default: sysconf(_SC_CLK_TCK))" },
-+ { "stat-mode", 's', "MODE", 0,
-+ "The [pid]/stat file publishes information which on Hurd is only "
-+ "available to the process owner. "
-+ "You can use this option to override its mode to be more permissive "
-+ "for compatibility purposes. "
-+ "(default: 0400)" },
-+ { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
-+ "Provide a fake \"self\" symlink to the given PID, for compatibility "
-+ "purposes. If PID is omitted, \"self\" will point to init. "
-+ "(default: no self link)" },
-+ { "kernel-process", 'k', "PID", 0,
-+ "Process identifier for the kernel, used to retreive its command "
-+ "line, as well as the global up and idle times. "
-+ "(default: 2)" },
-+ { "compatible", 'c', NULL, 0,
-+ "Try to be compatible with the Linux procps utilities. "
-+ "Currently equivalent to -h 100 -s 0444 -S 1." },
-+ { "anonymous-owner", 'a', "USER", 0,
-+ "Make USER the owner of files related to processes without one. "
-+ "Be aware that USER will be granted access to the environment and "
-+ "other sensitive information about the processes in question. "
-+ "(default: use uid 0)" },
-+ { "nodev", NODEV_KEY, NULL, 0,
-+ "Ignored for compatibility with Linux' procfs." },
-+ { "noexec", NOEXEC_KEY, NULL, 0,
-+ "Ignored for compatibility with Linux' procfs." },
-+ { "nosuid", NOSUID_KEY, NULL, 0,
-+ "Ignored for compatibility with Linux' procfs." },
-+ {}
-+};
-+
- struct argp argp = {
-- .options = (struct argp_option []) {
-- { "clk-tck", 'h', "HZ", 0,
-- "Unit used for the values expressed in system clock ticks "
-- "(default: sysconf(_SC_CLK_TCK))" },
-- { "stat-mode", 's', "MODE", 0,
-- "The [pid]/stat file publishes information which on Hurd is only "
-- "available to the process owner. "
-- "You can use this option to override its mode to be more permissive "
-- "for compatibility purposes. "
-- "(default: 0400)" },
-- { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
-- "Provide a fake \"self\" symlink to the given PID, for compatibility "
-- "purposes. If PID is omitted, \"self\" will point to init. "
-- "(default: no self link)" },
-- { "kernel-process", 'k', "PID", 0,
-- "Process identifier for the kernel, used to retreive its command "
-- "line, as well as the global up and idle times. "
-- "(default: 2)" },
-- { "compatible", 'c', NULL, 0,
-- "Try to be compatible with the Linux procps utilities. "
-- "Currently equivalent to -h 100 -s 0444 -S 1." },
-- { "anonymous-owner", 'a', "USER", 0,
-- "Make USER the owner of files related to processes without one. "
-- "Be aware that USER will be granted access to the environment and "
-- "other sensitive information about the processes in question. "
-- "(default: use uid 0)" },
-- { "nodev", NODEV_KEY, NULL, 0,
-- "Ignored for compatibility with Linux' procfs." },
-- { "noexec", NOEXEC_KEY, NULL, 0,
-- "Ignored for compatibility with Linux' procfs." },
-- { "nosuid", NOSUID_KEY, NULL, 0,
-- "Ignored for compatibility with Linux' procfs." },
-+ .options = common_options,
-+ .parser = argp_parser,
-+ .doc = "A virtual filesystem emulating the Linux procfs.",
-+ .children = (struct argp_child []) {
-+ { &netfs_std_startup_argp, },
- {}
- },
-+};
-+
-+static error_t
-+runtime_argp_parser (int key, char *arg, struct argp_state *state)
-+{
-+ switch (key)
-+ {
-+ case 'u':
-+ /* do nothing */
-+ break;
-+
-+ default:
-+ return ARGP_ERR_UNKNOWN;
-+ }
-+
-+ return 0;
-+}
-+
-+struct argp runtime_argp = {
-+ .options = (struct argp_option []) {
-+ { "update", 'u', NULL, 0, "remount; for procfs this does nothing" },
-+ {},
-+ },
-+ .parser = runtime_argp_parser,
-+};
-+
-+struct argp netfs_runtime_argp_ = {
-+ .options = common_options,
- .parser = argp_parser,
- .doc = "A virtual filesystem emulating the Linux procfs.",
- .children = (struct argp_child []) {
-- { &netfs_std_startup_argp, },
-+ { &runtime_argp, },
-+ { &netfs_std_runtime_argp, },
- {}
- },
- };
-
- /* Used by netfs_set_options to handle runtime option parsing. */
--struct argp *netfs_runtime_argp = &argp;
-+struct argp *netfs_runtime_argp = &netfs_runtime_argp_;
-
- error_t
- root_make_node (struct ps_context *pc, struct node **np)
---
-1.7.10.4
-
-
diff --git a/debian/patches/proxy-defpager.diff b/debian/patches/proxy-defpager.diff
index db9604ad..a83939c6 100644
--- a/debian/patches/proxy-defpager.diff
+++ b/debian/patches/proxy-defpager.diff
@@ -16,12 +16,12 @@ Index: hurd-debian/trans/Makefile
--- hurd-debian.orig/trans/Makefile 2012-11-26 00:23:22.000000000 +0000
+++ hurd-debian/trans/Makefile 2012-11-26 00:25:32.000000000 +0000
@@ -26,7 +26,7 @@
- fakeroot.c proxy-defpager.c remap.c
+ fakeroot.c proxy-defpager.c remap.c mtab.c
OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o \
crashServer.o crash_replyUser.o msgServer.o \
- default_pagerServer.o default_pagerUser.o \
+ ourdefault_pagerServer.o ourdefault_pagerUser.o \
- device_replyServer.o elfcore.o
+ device_replyServer.o elfcore.o fsysUser.o
HURDLIBS = ports netfs trivfs iohelp fshelp pipe ihash shouldbeinlibc
LDLIBS += -lpthread
@@ -34,6 +34,9 @@
diff --git a/debian/patches/series b/debian/patches/series
index 2e80be7b..f86b2a38 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,7 +1,4 @@
diskfs_no_inherit_dir_group.patch
-ext2fs_large_stores.patch
-ext2fs_large_stores_pthread.patch
-hurd_console_startup.patch
init_try_runsystem.gnu.patch
makedev.diff
pfinet_dhcp.patch
@@ -41,18 +38,5 @@ libmachdev.patch
exec_filename_exec.patch
exec_filename_fs.patch
exec_filename_use.patch
-
-# Justus Winter's work, to be pushed
-mount-n.patch
-mount-f.patch
-mount-remount.patch
mount-loop.patch
-procfs-update.patch
-procfs-default.patch
-procfs-get-options.patch
-sutils-types.patch
mount-test-opts.patch
-mount-ignore-mounted-all.patch
-mount-t-auto.patch
-sutils-multiple-none.patch
-umount.patch
diff --git a/debian/patches/sutils-multiple-none.patch b/debian/patches/sutils-multiple-none.patch
deleted file mode 100644
index c787b5a7..00000000
--- a/debian/patches/sutils-multiple-none.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-Previously it was not possible to add two mount entries with the same
-device information to an fstab structure. This is easily fixed by
-breaking the assumption, that there is only one possible mount entry
-for the "none" device as used by many purely virtual file systems.
-
-* utils/fstab.c (fstab_find_device): Return NULL if name is "none".
----
- sutils/fstab.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/sutils/fstab.c b/sutils/fstab.c
-index e241de6..d3b8b6f 100644
---- a/sutils/fstab.c
-+++ b/sutils/fstab.c
-@@ -457,11 +457,19 @@ fs_remount (struct fs *fs)
- return err;
- }
-
--/* Returns the FS entry in FSTAB with the device field NAME (there can only
-- be one such entry). */
-+/* Returns the FS entry in FSTAB with the device field NAME.
-+
-+ In general there can only be one such entry. This holds not true
-+ for virtual file systems that use "none" as device name.
-+
-+ If name is "none", NULL is returned. This also makes it possible to
-+ add more than one entry for the device "none". */
- inline struct fs *
- fstab_find_device (const struct fstab *fstab, const char *name)
- {
-+ if (strcmp (name, "none") == 0)
-+ return NULL;
-+
- struct fs *fs;
- for (fs = fstab->entries; fs; fs = fs->next)
- if (strcmp (fs->mntent.mnt_fsname, name) == 0)
---
-1.7.10.4
-
-
diff --git a/debian/patches/sutils-types.patch b/debian/patches/sutils-types.patch
deleted file mode 100644
index d2a21e94..00000000
--- a/debian/patches/sutils-types.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-The mount utility on both Linux and FreeBSD allows one to either
-specify a whitelist or a blacklist of filesystem types to consider for
---all. Prefixing the list with "no" indicates that the list is a
-blacklist. Furthermore, Linux' mount utility ignores a "no" prefix on
-any entry in the given list.
-
-Previously the Hurd variant first applied whitelist containing all
-positive values given and then filtered the resulting list using all
-negative values. But this makes little sense because each entry only
-has one value for the filesystem type (mnt_type) and all values are
-mutually exclusive.
-
-This patch adjusts the fstab handling code so that our mount utility
-behaves like the Linux mount utility. This code is used by both mount
-and fsck. The same argumentation applies to fsck as well.
-
-Like implemented in Linux mount, any "no" prefix is ignored to retain
-compatibility with the old behavior.
-
-* sutils/fstab.c (fstab_argp_create): Fix semantic of --types.
----
- sutils/fstab.c | 103 +++++++++++++++-----------------------------------------
- 1 file changed, 27 insertions(+), 76 deletions(-)
-
-diff --git a/sutils/fstab.c b/sutils/fstab.c
-index b66e519..e241de6 100644
---- a/sutils/fstab.c
-+++ b/sutils/fstab.c
-@@ -880,90 +880,41 @@ fstab_argp_create (struct fstab_argp_params *params,
- check = fstab;
- else
- {
-- struct fs *fs;
-- const char *tn;
-- unsigned int nonexclude_types;
--
- err = fstab_create (types, &check);
- if (err)
- error (105, err, "fstab_create");
-
-- /* For each excluded type (i.e. `-t notype'), clobber the
-- fstype entry's program with an empty string to mark it. */
-- nonexclude_types = 0;
-- for (tn = params->types; tn;
-- tn = argz_next (params->types, params->types_len, tn))
-- {
-- if (!strncasecmp (tn, "no", 2))
-- {
-- struct fstype *type;
-- err = fstypes_get (types, &tn[2], &type);
-- if (err)
-- error (106, err, "fstypes_get");
-- free (type->program);
-- type->program = strdup ("");
-- }
-- else
-- ++nonexclude_types;
-- }
--
-- if (nonexclude_types != 0)
-- {
-- const char *tn;
-- struct fstypes *wanttypes;
--
-- /* We will copy the types we want to include into a fresh
-- list in WANTTYPES. Since we specify no search formats,
-- `fstypes_get' applied to WANTTYPES can only create
-- elements with a null `program' field. */
-- err = fstypes_create (0, 0, &wanttypes);
-- if (err)
-- error (102, err, "fstypes_create");
--
-- for (tn = params->types; tn;
-- tn = argz_next (params->types, params->types_len, tn))
-- if (strncasecmp (tn, "no", 2))
-- {
-- struct fstype *type;
-- err = fstypes_get (types, tn, &type);
-- if (err)
-- error (106, err, "fstypes_get");
-- if (type->program == 0)
-- error (0, 0,
-- "requested filesystem type `%s' unknown", tn);
-- else
-- {
-- struct fstype *newtype = malloc (sizeof *newtype);
-- newtype->name = strdup (type->name);
-- newtype->program = strdup (type->program);
-- newtype->next = wanttypes->entries;
-- wanttypes->entries = newtype;
-- }
-- }
--
-- /* fstypes_free (types); */
-- types = wanttypes;
-- }
-+ int blacklist = strncasecmp (params->types, "no", 2) == 0;
-+ if (blacklist)
-+ params->types += 2; /* Skip no. */
-
-+ struct fs *fs;
- for (fs = fstab->entries; fs; fs = fs->next)
- {
-- const char *ptn;
-- struct fstype *type;
--
-- err = fs_type (fs, &type);
-- if (err || nonexclude_types)
-- {
-- err = fstypes_get (types, fs->mntent.mnt_type, &type);
-- if (err)
-- error (106, err, "fstypes_get");
-- if (params->types != 0)
-- continue;
-- }
-- if (nonexclude_types && type->program == 0)
-- continue; /* Freshly created, was not in WANTTYPES. */
-- if (type->program != 0 && type->program[0] == '\0')
-- continue; /* This type is marked as excluded. */
-+ if (strcmp (fs->mntent.mnt_type, MNTTYPE_SWAP) == 0)
-+ continue; /* Ignore swap entries. */
-+
-+ const char *tn;
-+ int matched = 0;
-+ for (tn = params->types; tn;
-+ tn = argz_next (params->types, params->types_len, tn))
-+ {
-+ const char *type = fs->mntent.mnt_type;
-+ if (strcmp (type, tn) == 0
-+ /* Skip no for compatibility. */
-+ || ((strncasecmp (type, "no", 2) == 0)
-+ && strcmp (type, tn) == 0))
-+ {
-+ matched = 1;
-+ break;
-+ }
-+ }
-+
-+ if (matched == blacklist)
-+ continue; /* Either matched and types is a blacklist
-+ or not matched and types is a whitelist */
-
-+ const char *ptn;
- for (ptn = params->exclude; ptn;
- ptn = argz_next (params->exclude, params->exclude_len, ptn))
- if (fnmatch (ptn, fs->mntent.mnt_dir, 0) == 0)
---
-1.7.10.4
-
-
diff --git a/debian/patches/umount.patch b/debian/patches/umount.patch
deleted file mode 100644
index b2f1cafa..00000000
--- a/debian/patches/umount.patch
+++ /dev/null
@@ -1,382 +0,0 @@
-This adds a umount utility that implements most of the functions that
-the Linux umount utility provides, especially that subset that is used
-by the Debian package initscripts.
-
-* utils/umount.c: New file.
----
- utils/Makefile | 10 +-
- utils/umount.c | 319 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 325 insertions(+), 4 deletions(-)
- create mode 100644 utils/umount.c
-
-diff --git a/utils/Makefile b/utils/Makefile
-index 207c904..4fe2dc2 100644
---- a/utils/Makefile
-+++ b/utils/Makefile
-@@ -21,7 +21,9 @@ makemode := utilities
- targets = shd ps settrans showtrans syncfs fsysopts \
- storeinfo login w uptime ids loginpr sush vmstat portinfo \
- devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \
-- storeread msgport rpctrace mount gcore fakeauth fakeroot remap
-+ storeread msgport rpctrace mount gcore fakeauth fakeroot remap \
-+ umount
-+
- special-targets = loginpr sush uptime fakeroot remap
- SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
- fsysopts.c storeinfo.c login.c loginpr.sh sush.sh w.c \
-@@ -29,7 +31,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
- parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \
- unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \
- rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \
-- match-options.c
-+ match-options.c umount.c
-
- OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
- HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
-@@ -58,7 +60,7 @@ ftpcp ftpdir: ../libftpconn/libftpconn.a
- settrans: ../libfshelp/libfshelp.a ../libports/libports.a
- ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \
- devprobe vminfo addauth rmauth setauth unsu ftpcp ftpdir storeread \
-- storecat msgport mount: \
-+ storecat msgport mount umount: \
- ../libshouldbeinlibc/libshouldbeinlibc.a
-
- $(filter-out $(special-targets), $(targets)): %: %.o
-@@ -74,7 +76,7 @@ fakeauth-CPPFLAGS = -I$(srcdir)/../auth
- authServer-CPPFLAGS = -I$(srcdir)/../auth
- auth_requestUser-CPPFLAGS = -I$(srcdir)/../auth
-
--mount: ../sutils/fstab.o ../sutils/clookup.o match-options.o \
-+mount umount: ../sutils/fstab.o ../sutils/clookup.o match-options.o \
- $(foreach L,fshelp ports,../lib$L/lib$L.a)
- ../sutils/fstab.o ../sutils/clookup.o: FORCE
- $(MAKE) -C $(@D) $(@F)
-diff --git a/utils/umount.c b/utils/umount.c
-new file mode 100644
-index 0000000..64e6ee2
---- /dev/null
-+++ b/utils/umount.c
-@@ -0,0 +1,319 @@
-+/* Roughly Unix/Linux-compatible `umount' frontend for Hurd translators.
-+
-+ Copyright (C) 2013 Free Software Foundation, Inc.
-+ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
-+
-+ 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 this program; if not, write to the Free Software
-+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-+
-+#include "../sutils/fstab.h"
-+#include <argp.h>
-+#include <argz.h>
-+#include <blkid/blkid.h>
-+#include <error.h>
-+#include <fcntl.h>
-+#include <hurd/fshelp.h>
-+#include <hurd/fsys.h>
-+#include <hurd/paths.h>
-+#include <hurd/process.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+
-+#include "match-options.h"
-+
-+/* XXX fix libc */
-+#undef _PATH_MOUNTED
-+#define _PATH_MOUNTED "/etc/mtab"
-+
-+static char *targets;
-+static size_t targets_len;
-+static int readonly;
-+static int verbose;
-+static int passive_flags = FS_TRANS_SET;
-+static int active_flags = FS_TRANS_SET;
-+static int goaway_flags;
-+static int fake;
-+
-+static struct fstab_argp_params fstab_params;
-+
-+#define FAKE_KEY 0x80 /* !isascii (FAKE_KEY), so no short option. */
-+
-+static const struct argp_option argp_opts[] =
-+{
-+ {"fake", FAKE_KEY, 0, 0, "Do not actually umount, just pretend"},
-+ {"force", 'f', 0, 0, "Force umount by killing the translator"},
-+ {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
-+ {"read-only", 'r', 0, 0, "If unmounting fails, try to remount read-only"},
-+ {"nosync", 'S', 0, 0, "Don't sync a translator before killing it"},
-+ {"test-opts", 'O', "OPTIONS", 0,
-+ "Only mount fstab entries matching the given set of options"},
-+ {"verbose", 'v', 0, 0, "Give more detailed information"},
-+ {},
-+};
-+
-+static error_t
-+parse_opt (int key, char *arg, struct argp_state *state)
-+{
-+ struct fstab_argp_params *params = state->input;
-+ error_t err;
-+ switch (key)
-+ {
-+ case ARGP_KEY_INIT:
-+ state->child_inputs[0] = params; /* pass down to fstab_argp parser */
-+ break;
-+
-+ case FAKE_KEY:
-+ fake = 1;
-+ break;
-+
-+ case 'f':
-+ goaway_flags |= FSYS_GOAWAY_FORCE;
-+ break;
-+
-+ case 'n':
-+ /* do nothing */
-+ break;
-+
-+ case 'r':
-+ readonly = 1;
-+ break;
-+
-+ case 'S':
-+ goaway_flags |= FSYS_GOAWAY_NOSYNC;
-+ break;
-+
-+ case 'O':
-+ err = argz_create_sep (arg, ',', &test_opts, &test_opts_len);
-+ if (err)
-+ argp_failure (state, 100, ENOMEM, "%s", arg);
-+ break;
-+
-+ case 'v':
-+ verbose += 1;
-+ break;
-+
-+ case ARGP_KEY_ARG:
-+ err = argz_add (&targets, &targets_len, arg);
-+ if (err)
-+ argp_failure (state, 100, ENOMEM, "%s", arg);
-+ break;
-+
-+ case ARGP_KEY_NO_ARGS:
-+ if (! params->do_all)
-+ {
-+ argp_error (state,
-+ "filesystem argument required if --all is not given");
-+ return EINVAL;
-+ }
-+ break;
-+
-+ case ARGP_KEY_END:
-+ if (params->do_all && targets)
-+ {
-+ argp_error (state, "filesystem argument not allowed with --all");
-+ return EINVAL;
-+ }
-+ break;
-+
-+ default:
-+ return ARGP_ERR_UNKNOWN;
-+ }
-+
-+ return 0;
-+}
-+
-+static const char doc[] = "Stop active and remove passive translators";
-+static const char args_doc[] = "DEVICE|DIRECTORY [DEVICE|DIRECTORY ...]";
-+
-+static struct argp fstab_argp_mtab; /* Slightly modified version. */
-+
-+static const struct argp_child argp_kids[] =
-+{
-+ {&fstab_argp_mtab, 0,
-+ "Filesystem selection (if no explicit filesystem arguments given):", 2},
-+ {},
-+};
-+static struct argp argp =
-+{
-+ options: argp_opts,
-+ parser: parse_opt,
-+ args_doc: args_doc,
-+ doc: doc,
-+ children: argp_kids,
-+};
-+
-+/* This is a trimmed and slightly modified version of
-+ fstab_argp.options which uses _PATH_MOUNTED instead of _PATH_MNTTAB
-+ in the doc strings. */
-+static const struct argp_option fstab_argp_mtab_opts[] =
-+{
-+ {"all", 'a', 0, 0, "Do all filesystems in " _PATH_MOUNTED},
-+ {0, 'A', 0, OPTION_ALIAS },
-+ {"fstab", 'F', "FILE", 0, "File to use instead of " _PATH_MOUNTED},
-+ {"fstype", 't', "TYPE", 0, "Do only filesystems of given type(s)"},
-+ {"exclude-root",'R',0, 0,
-+ "Exclude root (/) filesystem from " _PATH_MOUNTED " list"},
-+ {"exclude", 'X', "PATTERN", 0, "Exclude directories matching PATTERN"},
-+ {}
-+};
-+
-+static error_t
-+fstab_argp_mtab_parse_opt (int key, char *arg, struct argp_state *state)
-+{
-+ return fstab_argp.parser (key, arg, state);
-+}
-+
-+static struct argp fstab_argp_mtab =
-+{
-+ options: fstab_argp_mtab_opts,
-+ parser: fstab_argp_mtab_parse_opt,
-+};
-+
-+/* Unmount one filesystem. */
-+static error_t
-+do_umount (struct fs *fs)
-+{
-+ error_t err = 0;
-+
-+ file_t node = file_name_lookup(fs->mntent.mnt_dir, O_NOTRANS, 0666);
-+ if (node == MACH_PORT_NULL)
-+ {
-+ error(0, errno, "%s", fs->mntent.mnt_dir);
-+ return errno;
-+ }
-+
-+ if (verbose)
-+ printf ("settrans -pg%s%s %s\n",
-+ goaway_flags & FSYS_GOAWAY_NOSYNC? "S": "",
-+ goaway_flags & FSYS_GOAWAY_FORCE? "f": "",
-+ fs->mntent.mnt_dir);
-+
-+ if (! fake)
-+ {
-+ err = file_set_translator (node,
-+ passive_flags, active_flags, goaway_flags,
-+ NULL, 0,
-+ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
-+ if (err)
-+ {
-+ error (0, err, "%s", fs->mntent.mnt_dir);
-+
-+ /* Try remounting readonly instead if requested. */
-+ if (readonly)
-+ {
-+ if (verbose)
-+ printf ("fsysopts %s --readonly\n", fs->mntent.mnt_dir);
-+
-+ error_t e = fs_set_readonly (fs, TRUE);
-+ if (e)
-+ error (0, e, "%s", fs->mntent.mnt_dir);
-+ }
-+ }
-+ }
-+
-+ /* Deallocate the reference so that unmounting nested translators
-+ works properly. */
-+ mach_port_deallocate (mach_task_self (), node);
-+ return err;
-+}
-+
-+int
-+main (int argc, char **argv)
-+{
-+ error_t err;
-+
-+ err = argp_parse (&argp, argc, argv, 0, 0, &fstab_params);
-+ if (err)
-+ error (3, err, "parsing arguments");
-+
-+ /* Read the mtab file by default. */
-+ if (! fstab_params.fstab_path)
-+ fstab_params.fstab_path = _PATH_MOUNTED;
-+
-+ struct fstab *fstab = fstab_argp_create (&fstab_params, NULL, 0);
-+ if (! fstab)
-+ error (3, ENOMEM, "fstab creation");
-+
-+ if (targets)
-+ for (char *t = targets; t; t = argz_next (targets, targets_len, t))
-+ {
-+ /* Figure out if t is the device or the mountpoint. */
-+ struct fs *fs = fstab_find_mount (fstab, t);
-+ if (! fs)
-+ {
-+ fs = fstab_find_device (fstab, t);
-+ if (! fs)
-+ {
-+ error (0, 0, "could not find entry for: %s", t);
-+
-+ /* As last resort, just assume it is the mountpoint. */
-+ struct mntent m =
-+ {
-+ mnt_fsname: "",
-+ mnt_dir: t,
-+ mnt_type: "",
-+ mnt_opts: 0,
-+ mnt_freq: 0,
-+ mnt_passno: 0,
-+ };
-+
-+ err = fstab_add_mntent (fstab, &m, &fs);
-+ if (err)
-+ error (2, err, "%s", t);
-+ }
-+ }
-+
-+ if (fs)
-+ err |= do_umount (fs);
-+ }
-+ else
-+ {
-+ /* Sort entries. */
-+ size_t count = 0;
-+ for (struct fs *fs = fstab->entries; fs; fs = fs->next)
-+ count += 1;
-+
-+ char **entries = malloc (count * sizeof (char *));
-+ if (! entries)
-+ error (3, ENOMEM, "allocating entries array");
-+
-+ char **p = entries;
-+ for (struct fs *fs = fstab->entries; fs; fs = fs->next)
-+ *p++ = fs->mntent.mnt_dir;
-+
-+ /* Reverse lexicographical order. */
-+ int compare_entries (const void *a, const void *b)
-+ {
-+ return -strcmp ((char *) a, (char *) b);
-+ }
-+
-+ qsort (entries, count, sizeof (char *), compare_entries);
-+
-+ for (int i = 0; i < count; i++)
-+ {
-+ struct fs *fs = fstab_find_mount (fstab, entries[i]);
-+ if (! fs)
-+ error (4, 0, "could not find entry for: %s", entries[i]);
-+
-+ if (! match_options (&fs->mntent))
-+ continue;
-+
-+ err |= do_umount (fs);
-+ }
-+ }
-+
-+ return err? EXIT_FAILURE: EXIT_SUCCESS;
-+}
---
-1.7.10.4
-
-