summaryrefslogtreecommitdiff
path: root/debian/patches/0010-libdiskfs-implement-a-node-cache.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0010-libdiskfs-implement-a-node-cache.patch')
-rw-r--r--debian/patches/0010-libdiskfs-implement-a-node-cache.patch687
1 files changed, 0 insertions, 687 deletions
diff --git a/debian/patches/0010-libdiskfs-implement-a-node-cache.patch b/debian/patches/0010-libdiskfs-implement-a-node-cache.patch
deleted file mode 100644
index c0c42926..00000000
--- a/debian/patches/0010-libdiskfs-implement-a-node-cache.patch
+++ /dev/null
@@ -1,687 +0,0 @@
-From 2bb8bfa49d35ab2f7b33587e59c4a9c635642ea0 Mon Sep 17 00:00:00 2001
-From: Justus Winter <4winter@informatik.uni-hamburg.de>
-Date: Wed, 15 Apr 2015 13:17:06 +0200
-Subject: [PATCH hurd 10/16] libdiskfs: implement a node cache
-
-xxx
-
-Move the node cache from ext2fs into libdiskfs.
-
-* ext2fs/dir.c
-* ext2fs/ext2fs.c
-* ext2fs/ext2fs.h
-* ext2fs/inode.c
-* libdiskfs/Makefile
-* libdiskfs/diskfs.h
-* libdiskfs/node-cache.c
----
- ext2fs/dir.c | 4 +-
- ext2fs/ext2fs.c | 2 -
- ext2fs/ext2fs.h | 9 --
- ext2fs/inode.c | 228 ++++----------------------------------------
- libdiskfs/Makefile | 2 +-
- libdiskfs/diskfs.h | 17 ++++
- libdiskfs/node-cache.c | 249 +++++++++++++++++++++++++++++++++++++++++++++++++
- 7 files changed, 289 insertions(+), 222 deletions(-)
- create mode 100644 libdiskfs/node-cache.c
-
-diff --git a/ext2fs/dir.c b/ext2fs/dir.c
-index 2dfe1d7..6cdfba2 100644
---- a/ext2fs/dir.c
-+++ b/ext2fs/dir.c
-@@ -306,7 +306,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
-
- /* Here below are the spec dotdot cases. */
- else if (type == RENAME || type == REMOVE)
-- np = ifind (inum);
-+ np = diskfs_cached_ifind (inum);
-
- else if (type == LOOKUP)
- {
-@@ -359,7 +359,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
- diskfs_nput (np);
- }
- else if (type == RENAME || type == REMOVE)
-- /* We just did ifind to get np; that allocates
-+ /* We just did diskfs_cached_ifind to get np; that allocates
- no new references, so we don't have anything to do */
- ;
- else if (type == LOOKUP)
-diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c
-index beb7cad..d0fdfe7 100644
---- a/ext2fs/ext2fs.c
-+++ b/ext2fs/ext2fs.c
-@@ -185,8 +185,6 @@ main (int argc, char **argv)
-
- map_hypermetadata ();
-
-- inode_init ();
--
- /* Set diskfs_root_node to the root inode. */
- err = diskfs_cached_lookup (EXT2_ROOT_INO, &diskfs_root_node);
- if (err)
-diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
-index 9667b6f..96d8e9d 100644
---- a/ext2fs/ext2fs.h
-+++ b/ext2fs/ext2fs.h
-@@ -159,9 +159,6 @@ struct disknode
- each DIRBLKSIZE piece of the directory. */
- int *dirents;
-
-- /* Links on hash list. */
-- struct node *hnext, **hprevp;
--
- /* Lock to lock while fiddling with this inode's block allocation info. */
- pthread_rwlock_t alloc_lock;
-
-@@ -419,12 +416,6 @@ dino_deref (struct ext2_inode *inode)
-
- /* Write all active disknodes into the inode pager. */
- void write_all_disknodes ();
--
--/* Lookup node INUM (which must have a reference already) and return it
-- without allocating any new references. */
--struct node *ifind (ino_t inum);
--
--void inode_init (void);
-
- /* ---------------------------------------------------------------- */
-
-diff --git a/ext2fs/inode.c b/ext2fs/inode.c
-index 7af617c..22a0c8e 100644
---- a/ext2fs/inode.c
-+++ b/ext2fs/inode.c
-@@ -39,144 +39,34 @@
- #define UF_IMMUTABLE 0
- #endif
-
--#define INOHSZ 8192
--#if ((INOHSZ&(INOHSZ-1)) == 0)
--#define INOHASH(ino) ((ino)&(INOHSZ-1))
--#else
--#define INOHASH(ino) (((unsigned)(ino))%INOHSZ)
--#endif
--
--/* The nodehash is a cache of nodes.
--
-- Access to nodehash and nodehash_nr_items is protected by
-- nodecache_lock.
--
-- Every node in the nodehash carries a light reference. When we are
-- asked to give up that light reference, we reacquire our lock
-- momentarily to check whether someone else reacquired a reference
-- through the nodehash. */
--static struct node *nodehash[INOHSZ];
--static size_t nodehash_nr_items;
--static pthread_rwlock_t nodecache_lock = PTHREAD_RWLOCK_INITIALIZER;
--
- static error_t read_node (struct node *np);
-
- pthread_spinlock_t generation_lock = PTHREAD_SPINLOCK_INITIALIZER;
-
--/* Initialize the inode hash table. */
--void
--inode_init ()
--{
-- int n;
-- for (n = 0; n < INOHSZ; n++)
-- nodehash[n] = 0;
--}
--
--/* Lookup node with inode number INUM. Returns NULL if the node is
-- not found in the node cache. */
--static struct node *
--lookup (ino_t inum)
--{
-- struct node *np;
-- for (np = nodehash[INOHASH(inum)]; np; np = diskfs_node_disknode (np)->hnext)
-- if (np->cache_id == inum)
-- return np;
-- return NULL;
--}
--
--/* Fetch inode INUM, set *NPP to the node structure;
-- gain one user reference and lock the node. */
-+/* XXX */
- error_t
--diskfs_cached_lookup (ino_t inum, struct node **npp)
-+diskfs_user_make_node (struct node **npp)
- {
-- error_t err;
-- struct node *np, *tmp;
-+ struct node *np;
- struct disknode *dn;
-
-- pthread_rwlock_rdlock (&nodecache_lock);
-- np = lookup (inum);
-- if (np)
-- goto gotit;
-- pthread_rwlock_unlock (&nodecache_lock);
--
- /* Create the new node. */
- np = diskfs_make_node_alloc (sizeof *dn);
-- dn = diskfs_node_disknode (np);
-- np->cache_id = inum;
-+ if (np == NULL)
-+ return ENOMEM;
-
- /* Format specific data for the new node. */
-+ dn = diskfs_node_disknode (np);
- dn->dirents = 0;
- dn->dir_idx = 0;
- dn->pager = 0;
- pthread_rwlock_init (&dn->alloc_lock, NULL);
- pokel_init (&dn->indir_pokel, diskfs_disk_pager, disk_cache);
-
-- pthread_mutex_lock (&np->lock);
--
-- /* Put NP in NODEHASH. */
-- pthread_rwlock_wrlock (&nodecache_lock);
-- tmp = lookup (inum);
-- if (tmp)
-- {
-- /* We lost a race. */
-- diskfs_nput (np);
-- np = tmp;
-- goto gotit;
-- }
--
-- dn->hnext = nodehash[INOHASH(inum)];
-- if (dn->hnext)
-- diskfs_node_disknode (dn->hnext)->hprevp = &dn->hnext;
-- dn->hprevp = &nodehash[INOHASH(inum)];
-- nodehash[INOHASH(inum)] = np;
-- diskfs_nref_light (np);
-- nodehash_nr_items += 1;
-- pthread_rwlock_unlock (&nodecache_lock);
--
-- /* Get the contents of NP off disk. */
-- err = read_node (np);
--
-- if (!diskfs_check_readonly () && !np->dn_stat.st_gen)
-- {
-- pthread_spin_lock (&generation_lock);
-- if (++next_generation < diskfs_mtime->seconds)
-- next_generation = diskfs_mtime->seconds;
-- np->dn_stat.st_gen = next_generation;
-- pthread_spin_unlock (&generation_lock);
-- np->dn_set_ctime = 1;
-- }
--
-- if (err)
-- return err;
-- else
-- {
-- *npp = np;
-- return 0;
-- }
--
-- gotit:
-- diskfs_nref (np);
-- pthread_rwlock_unlock (&nodecache_lock);
-- pthread_mutex_lock (&np->lock);
- *npp = np;
- return 0;
- }
-
--/* Lookup node INUM (which must have a reference already) and return it
-- without allocating any new references. */
--struct node *
--ifind (ino_t inum)
--{
-- struct node *np;
--
-- pthread_rwlock_rdlock (&nodecache_lock);
-- np = lookup (inum);
-- pthread_rwlock_unlock (&nodecache_lock);
--
-- assert (np);
-- return np;
--}
--
- /* The last reference to a node has gone away; drop
- it from the hash table and clean all state in the dn structure. */
- void
-@@ -196,35 +86,8 @@ diskfs_node_norefs (struct node *np)
- /* The last hard reference to a node has gone away; arrange to have
- all the weak references dropped that can be. */
- void
--diskfs_try_dropping_softrefs (struct node *np)
-+diskfs_user_try_dropping_softrefs (struct node *np)
- {
-- pthread_rwlock_wrlock (&nodecache_lock);
-- if (diskfs_node_disknode (np)->hprevp != NULL)
-- {
-- /* Check if someone reacquired a reference through the
-- nodehash. */
-- struct references result;
-- refcounts_references (&np->refcounts, &result);
--
-- if (result.hard > 0)
-- {
-- /* A reference was reacquired through a hash table lookup.
-- It's fine, we didn't touch anything yet. */
-- pthread_rwlock_unlock (&nodecache_lock);
-- return;
-- }
--
-- *diskfs_node_disknode (np)->hprevp = diskfs_node_disknode (np)->hnext;
-- if (diskfs_node_disknode (np)->hnext)
-- diskfs_node_disknode (diskfs_node_disknode (np)->hnext)->hprevp =
-- diskfs_node_disknode (np)->hprevp;
-- diskfs_node_disknode (np)->hnext = NULL;
-- diskfs_node_disknode (np)->hprevp = NULL;
-- nodehash_nr_items -= 1;
-- diskfs_nrele_light (np);
-- }
-- pthread_rwlock_unlock (&nodecache_lock);
--
- drop_pager_softrefs (np);
- }
-
-@@ -243,8 +106,8 @@ diskfs_new_hardrefs (struct node *np)
- }
-
- /* Read stat information out of the ext2_inode. */
--static error_t
--read_node (struct node *np)
-+error_t
-+diskfs_user_read_node (struct node *np)
- {
- error_t err;
- struct stat *st = &np->dn_stat;
-@@ -384,6 +247,16 @@ read_node (struct node *np)
- linux, some devices). */
- np->allocsize = 0;
-
-+ if (!diskfs_check_readonly () && !np->dn_stat.st_gen)
-+ {
-+ pthread_spin_lock (&generation_lock);
-+ if (++next_generation < diskfs_mtime->seconds)
-+ next_generation = diskfs_mtime->seconds;
-+ np->dn_stat.st_gen = next_generation;
-+ pthread_spin_unlock (&generation_lock);
-+ np->dn_set_ctime = 1;
-+ }
-+
- return 0;
- }
-
-@@ -585,72 +458,11 @@ diskfs_node_reload (struct node *node)
- }
- pokel_flush (&dn->indir_pokel);
- flush_node_pager (node);
-- read_node (node);
-+ diskfs_user_read_node (node);
-
- return 0;
- }
-
--/* For each active node, call FUN. The node is to be locked around the call
-- to FUN. If FUN returns non-zero for any node, then immediately stop, and
-- return that value. */
--error_t
--diskfs_node_iterate (error_t (*fun)(struct node *))
--{
-- error_t err = 0;
-- int n;
-- size_t num_nodes;
-- struct node *node, **node_list, **p;
--
-- pthread_rwlock_rdlock (&nodecache_lock);
--
-- /* We must copy everything from the hash table into another data structure
-- to avoid running into any problems with the hash-table being modified
-- during processing (normally we delegate access to hash-table with
-- nodecache_lock, but we can't hold this while locking the
-- individual node locks). */
-- num_nodes = nodehash_nr_items;
--
-- /* TODO This method doesn't scale beyond a few dozen nodes and should be
-- replaced. */
-- node_list = malloc (num_nodes * sizeof (struct node *));
-- if (node_list == NULL)
-- {
-- pthread_rwlock_unlock (&nodecache_lock);
-- ext2_debug ("unable to allocate temporary node table");
-- return ENOMEM;
-- }
--
-- p = node_list;
-- for (n = 0; n < INOHSZ; n++)
-- for (node = nodehash[n]; node; node = diskfs_node_disknode (node)->hnext)
-- {
-- *p++ = node;
--
-- /* We acquire a hard reference for node, but without using
-- diskfs_nref. We do this so that diskfs_new_hardrefs will not
-- get called. */
-- refcounts_ref (&node->refcounts, NULL);
-- }
--
-- pthread_rwlock_unlock (&nodecache_lock);
--
-- p = node_list;
-- while (num_nodes-- > 0)
-- {
-- node = *p++;
-- if (!err)
-- {
-- pthread_mutex_lock (&node->lock);
-- err = (*fun)(node);
-- pthread_mutex_unlock (&node->lock);
-- }
-- diskfs_nrele (node);
-- }
--
-- free (node_list);
-- return err;
--}
--
- /* Write all active disknodes into the ext2_inode pager. */
- void
- write_all_disknodes ()
-diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile
-index 996e86a..47b9339 100644
---- a/libdiskfs/Makefile
-+++ b/libdiskfs/Makefile
-@@ -41,7 +41,7 @@ OTHERSRCS = conch-fetch.c conch-set.c dir-clear.c dir-init.c dir-renamed.c \
- extern-inline.c \
- node-create.c node-drop.c node-make.c node-rdwr.c node-update.c \
- node-nref.c node-nput.c node-nrele.c node-nrefl.c node-nputl.c \
-- node-nrelel.c \
-+ node-nrelel.c node-cache.c \
- peropen-make.c peropen-rele.c protid-make.c protid-rele.c \
- init-init.c init-startup.c init-first.c init-main.c \
- rdwr-internal.c boot-start.c demuxer.c node-times.c shutdown.c \
-diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
-index 7a21dff..22c4aa6 100644
---- a/libdiskfs/diskfs.h
-+++ b/libdiskfs/diskfs.h
-@@ -80,6 +80,9 @@ struct peropen
- filesystem. */
- struct node
- {
-+ /* Links on hash list. */
-+ struct node *hnext, **hprevp;
-+
- struct disknode *dn;
-
- io_statbuf_t dn_stat;
-@@ -1102,4 +1105,18 @@ struct store *diskfs_init_main (struct argp *startup_argp,
- /* Make errors go somewhere reasonable. */
- void diskfs_console_stdio ();
-
-+//XXX
-+/* XXX */
-+error_t diskfs_user_make_node (struct node **npp);
-+/* Read stat information out of the ext2_inode. */
-+error_t diskfs_user_read_node (struct node *np);
-+/* The last hard reference to a node has gone away; arrange to have
-+ all the weak references dropped that can be. */
-+void diskfs_user_try_dropping_softrefs (struct node *np);
-+
-+/* Lookup node INUM (which must have a reference already) and return it
-+ without allocating any new references. */
-+struct node *diskfs_cached_ifind (ino_t inum);
-+
-+
- #endif /* hurd/diskfs.h */
-diff --git a/libdiskfs/node-cache.c b/libdiskfs/node-cache.c
-new file mode 100644
-index 0000000..58249bf
---- /dev/null
-+++ b/libdiskfs/node-cache.c
-@@ -0,0 +1,249 @@
-+/* Inode cache.
-+
-+ Copyright (C) 1994-2015 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 it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#include "priv.h"
-+
-+#define INOHSZ 8192
-+#if ((INOHSZ&(INOHSZ-1)) == 0)
-+#define INOHASH(ino) ((ino)&(INOHSZ-1))
-+#else
-+#define INOHASH(ino) (((unsigned)(ino))%INOHSZ)
-+#endif
-+
-+/* The nodehash is a cache of nodes.
-+
-+ Access to nodehash and nodehash_nr_items is protected by
-+ nodecache_lock.
-+
-+ Every node in the nodehash carries a light reference. When we are
-+ asked to give up that light reference, we reacquire our lock
-+ momentarily to check whether someone else reacquired a reference
-+ through the nodehash. */
-+static struct node *nodehash[INOHSZ];
-+static size_t nodehash_nr_items;
-+static pthread_rwlock_t nodecache_lock = PTHREAD_RWLOCK_INITIALIZER;
-+
-+/* Initialize the inode hash table. */
-+static void __attribute__ ((constructor))
-+nodecache_init ()
-+{
-+}
-+
-+/* Lookup node with inode number INUM. Returns NULL if the node is
-+ not found in the node cache. */
-+static struct node *
-+lookup (ino_t inum)
-+{
-+ struct node *np;
-+ for (np = nodehash[INOHASH(inum)]; np; np = np->hnext)
-+ if (np->cache_id == inum)
-+ return np;
-+ return NULL;
-+}
-+
-+/* Fetch inode INUM, set *NPP to the node structure;
-+ gain one user reference and lock the node. */
-+error_t __attribute__ ((weak))
-+diskfs_cached_lookup (ino_t inum, struct node **npp)
-+{
-+ error_t err;
-+ struct node *np, *tmp;
-+
-+ pthread_rwlock_rdlock (&nodecache_lock);
-+ np = lookup (inum);
-+ if (np)
-+ goto gotit;
-+ pthread_rwlock_unlock (&nodecache_lock);
-+
-+ err = diskfs_user_make_node (&np);
-+ if (err)
-+ return err;
-+
-+ np->cache_id = inum;
-+ pthread_mutex_lock (&np->lock);
-+
-+ /* Put NP in NODEHASH. */
-+ pthread_rwlock_wrlock (&nodecache_lock);
-+ tmp = lookup (inum);
-+ if (tmp)
-+ {
-+ /* We lost a race. */
-+ diskfs_nput (np);
-+ np = tmp;
-+ goto gotit;
-+ }
-+
-+ np->hnext = nodehash[INOHASH(inum)];
-+ if (np->hnext)
-+ np->hnext->hprevp = &np->hnext;
-+ np->hprevp = &nodehash[INOHASH(inum)];
-+ nodehash[INOHASH(inum)] = np;
-+ diskfs_nref_light (np);
-+ nodehash_nr_items += 1;
-+ pthread_rwlock_unlock (&nodecache_lock);
-+
-+ /* Get the contents of NP off disk. */
-+ err = diskfs_user_read_node (np);
-+ if (err)
-+ return err;
-+ else
-+ {
-+ *npp = np;
-+ return 0;
-+ }
-+
-+ gotit:
-+ diskfs_nref (np);
-+ pthread_rwlock_unlock (&nodecache_lock);
-+ pthread_mutex_lock (&np->lock);
-+ *npp = np;
-+ return 0;
-+}
-+
-+/* Lookup node INUM (which must have a reference already) and return it
-+ without allocating any new references. */
-+struct node *
-+diskfs_cached_ifind (ino_t inum)
-+{
-+ struct node *np;
-+
-+ pthread_rwlock_rdlock (&nodecache_lock);
-+ np = lookup (inum);
-+ pthread_rwlock_unlock (&nodecache_lock);
-+
-+ assert (np);
-+ return np;
-+}
-+
-+void __attribute__ ((weak))
-+diskfs_try_dropping_softrefs (struct node *np)
-+{
-+ pthread_rwlock_wrlock (&nodecache_lock);
-+ if (np->hprevp != NULL)
-+ {
-+ /* Check if someone reacquired a reference through the
-+ nodehash. */
-+ struct references result;
-+ refcounts_references (&np->refcounts, &result);
-+
-+ if (result.hard > 0)
-+ {
-+ /* A reference was reacquired through a hash table lookup.
-+ It's fine, we didn't touch anything yet. */
-+ pthread_rwlock_unlock (&nodecache_lock);
-+ return;
-+ }
-+
-+ *np->hprevp = np->hnext;
-+ if (np->hnext)
-+ np->hnext->hprevp = np->hprevp;
-+ np->hnext = NULL;
-+ np->hprevp = NULL;
-+ nodehash_nr_items -= 1;
-+ diskfs_nrele_light (np);
-+ }
-+ pthread_rwlock_unlock (&nodecache_lock);
-+
-+ diskfs_user_try_dropping_softrefs (np);
-+}
-+
-+/* For each active node, call FUN. The node is to be locked around the call
-+ to FUN. If FUN returns non-zero for any node, then immediately stop, and
-+ return that value. */
-+error_t __attribute__ ((weak))
-+diskfs_node_iterate (error_t (*fun)(struct node *))
-+{
-+ error_t err = 0;
-+ int n;
-+ size_t num_nodes;
-+ struct node *node, **node_list, **p;
-+
-+ pthread_rwlock_rdlock (&nodecache_lock);
-+
-+ /* We must copy everything from the hash table into another data structure
-+ to avoid running into any problems with the hash-table being modified
-+ during processing (normally we delegate access to hash-table with
-+ nodecache_lock, but we can't hold this while locking the
-+ individual node locks). */
-+ /* XXX: Can we? */
-+ num_nodes = nodehash_nr_items;
-+
-+ /* TODO This method doesn't scale beyond a few dozen nodes and should be
-+ replaced. */
-+ node_list = malloc (num_nodes * sizeof (struct node *));
-+ if (node_list == NULL)
-+ {
-+ pthread_rwlock_unlock (&nodecache_lock);
-+ error (0, 0, "unable to allocate temporary node table");
-+ return ENOMEM;
-+ }
-+
-+ p = node_list;
-+ for (n = 0; n < INOHSZ; n++)
-+ for (node = nodehash[n]; node; node = node->hnext)
-+ {
-+ *p++ = node;
-+
-+ /* We acquire a hard reference for node, but without using
-+ diskfs_nref. We do this so that diskfs_new_hardrefs will not
-+ get called. */
-+ refcounts_ref (&node->refcounts, NULL);
-+ }
-+
-+ pthread_rwlock_unlock (&nodecache_lock);
-+
-+ p = node_list;
-+ while (num_nodes-- > 0)
-+ {
-+ node = *p++;
-+ if (!err)
-+ {
-+ pthread_mutex_lock (&node->lock);
-+ err = (*fun)(node);
-+ pthread_mutex_unlock (&node->lock);
-+ }
-+ diskfs_nrele (node);
-+ }
-+
-+ free (node_list);
-+ return err;
-+}
-+
-+/* XXX */
-+error_t __attribute__ ((weak))
-+diskfs_user_make_node (struct node **npp)
-+{
-+ assert (! "diskfs_user_make_node not implemented");
-+}
-+
-+/* Read stat information out of the ext2_inode. */
-+error_t __attribute__ ((weak))
-+diskfs_user_read_node (struct node *np)
-+{
-+ assert (! "diskfs_user_read_node not implemented");
-+}
-+
-+/* The last hard reference to a node has gone away; arrange to have
-+ all the weak references dropped that can be. */
-+void __attribute__ ((weak))
-+diskfs_user_try_dropping_softrefs (struct node *np)
-+{
-+ assert (! "diskfs_user_try_dropping_softrefs not implemented");
-+}
-+
---
-2.1.4
-