diff options
Diffstat (limited to 'debian/patches/0016-ext2fs-use-librbtree-for-the-nodehash.patch')
-rw-r--r-- | debian/patches/0016-ext2fs-use-librbtree-for-the-nodehash.patch | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/debian/patches/0016-ext2fs-use-librbtree-for-the-nodehash.patch b/debian/patches/0016-ext2fs-use-librbtree-for-the-nodehash.patch deleted file mode 100644 index fee4854f..00000000 --- a/debian/patches/0016-ext2fs-use-librbtree-for-the-nodehash.patch +++ /dev/null @@ -1,314 +0,0 @@ -From 54e3e8084aad34ddcd74aea215d83eb3f641d248 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 14 May 2014 15:30:19 +0200 -Subject: [PATCH 16/16] ext2fs: use librbtree for the nodehash - -Previously, a lookup of a node through nodehash took O(N / INOHSZ). -With INOHSZ being a constant (512) this is linear in N. Use a -red-black tree instead, which guarantees a lookup performance in -O(log N) time. - -* ext2fs/inode.c (INOHSZ, INOHASH): Remove. -(nodehash): Use a red-black tree. -(node_cmp_lookup, node_cmp_insert, node_get_np): New functions. -(inode_init): Remove. -(diskfs_cached_lookup): Adjust accordingly. -(ifind, diskfs_try_dropping_softrefs, diskfs_node_iterate): Likewise. -* ext2fs/ext2fs.h (struct disknode): Remove list pointers, add -red-black tree node. Because we store disknode objects in the tree, -we also need a pointer to the node object, and the cache_id for -efficient operations on the rb tree. -* ext2fs/ext2fs.c (main): Drop inode_init. ---- - ext2fs/Makefile | 2 +- - ext2fs/ext2fs.c | 2 - - ext2fs/ext2fs.h | 7 ++-- - ext2fs/inode.c | 124 +++++++++++++++++++++++++++++--------------------------- - 4 files changed, 70 insertions(+), 65 deletions(-) - -diff --git a/ext2fs/Makefile b/ext2fs/Makefile -index 8d2e68c..b075dc0 100644 ---- a/ext2fs/Makefile -+++ b/ext2fs/Makefile -@@ -23,7 +23,7 @@ target = ext2fs - SRCS = balloc.c dir.c ext2fs.c getblk.c hyper.c ialloc.c \ - inode.c pager.c pokel.c truncate.c storeinfo.c msg.c xinl.c - OBJS = $(SRCS:.c=.o) --HURDLIBS = diskfs pager iohelp fshelp store ports ihash shouldbeinlibc -+HURDLIBS = diskfs pager iohelp fshelp store ports ihash rbtree shouldbeinlibc - OTHERLIBS = -lpthread $(and $(HAVE_LIBBZ2),-lbz2) $(and $(HAVE_LIBZ),-lz) - - include ../Makeconf -diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c -index 128b6ed..0409dfb 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 3422af2..3505bb7 100644 ---- a/ext2fs/ext2fs.h -+++ b/ext2fs/ext2fs.h -@@ -26,6 +26,7 @@ - #include <hurd/store.h> - #include <hurd/diskfs.h> - #include <hurd/ihash.h> -+#include <hurd/rbtree.h> - #include <assert.h> - #include <pthread.h> - #include <sys/mman.h> -@@ -155,13 +156,13 @@ clear_bit (unsigned num, char *bitmap) - /* ext2fs specific per-file data. */ - struct disknode - { -+ /* Red-black-tree node for the node cache. */ -+ struct rbtree_node tree_node; -+ - /* For a directory, this array holds the number of directory entries in - 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; - -diff --git a/ext2fs/inode.c b/ext2fs/inode.c -index 7ec343f..0142bf6 100644 ---- a/ext2fs/inode.c -+++ b/ext2fs/inode.c -@@ -20,6 +20,7 @@ - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - #include "ext2fs.h" -+#include <stddef.h> - #include <string.h> - #include <unistd.h> - #include <stdio.h> -@@ -39,13 +40,6 @@ - #define UF_IMMUTABLE 0 - #endif - --#define INOHSZ 512 --#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 -@@ -55,23 +49,45 @@ - 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 struct rbtree nodehash = RBTREE_INITIALIZER; - static size_t nodehash_nr_items; - static pthread_mutex_t nodehash_lock = PTHREAD_MUTEX_INITIALIZER; - --static error_t read_node (struct node *np); -+static inline struct node * -+node_get_np (const struct rbtree_node *node) -+{ -+ struct disknode *dn; - --pthread_spinlock_t generation_lock = PTHREAD_SPINLOCK_INITIALIZER; -+ dn = rbtree_entry (node, struct disknode, tree_node); - --/* Initialize the inode hash table. */ --void --inode_init () -+ return diskfs_disknode_node (dn); -+} -+ -+static inline int -+node_cmp_lookup (const ino_t inum, -+ const struct rbtree_node *node) - { -- int n; -- for (n = 0; n < INOHSZ; n++) -- nodehash[n] = 0; -+ struct node *np = node_get_np (node); -+ -+ if (inum == np->cache_id) -+ return 0; -+ else if (inum < np->cache_id) -+ return -1; -+ else -+ return 1; - } - -+static inline int -+node_cmp_insert (const struct rbtree_node *a, -+ const struct rbtree_node *b) -+{ -+ return node_cmp_lookup (node_get_np (a)->cache_id, b); -+} -+ -+static error_t read_node (struct node *np); -+ -+pthread_spinlock_t generation_lock = PTHREAD_SPINLOCK_INITIALIZER; -+ - /* Fetch inode INUM, set *NPP to the node structure; - gain one user reference and lock the node. */ - error_t -@@ -79,47 +95,42 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - { - error_t err; - struct node *np; -+ struct rbtree_node *node; -+ unsigned long slot; - struct disknode *dn; - - pthread_mutex_lock (&nodehash_lock); -- for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) -- if (np->cache_id == inum) -- { -- diskfs_nref (np); -- pthread_mutex_unlock (&nodehash_lock); -- pthread_mutex_lock (&np->lock); -- *npp = np; -- return 0; -- } -- -- /* Format specific data for the new node. */ -- dn = malloc (sizeof (struct disknode)); -- if (! dn) -+ node = rbtree_lookup_slot (&nodehash, inum, node_cmp_lookup, slot); -+ if (node != NULL) -+ { -+ np = node_get_np (node); -+ diskfs_nref (np); -+ pthread_mutex_unlock (&nodehash_lock); -+ pthread_mutex_lock (&np->lock); -+ *npp = np; -+ return 0; -+ } -+ -+ /* Create the new node. */ -+ np = diskfs_make_node_alloc (sizeof *dn); -+ if (np == NULL) - { - pthread_mutex_unlock (&nodehash_lock); - return ENOMEM; - } -+ np->cache_id = inum; -+ 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); -- -- /* Create the new node. */ -- np = diskfs_make_node (dn); -- np->cache_id = inum; -- - pthread_mutex_lock (&np->lock); - - /* Put NP in NODEHASH. */ -- dn->hnext = nodehash[INOHASH(inum)]; -- if (dn->hnext) -- dn->hnext->dn->hprevp = &dn->hnext; -- dn->hprevp = &nodehash[INOHASH(inum)]; -- nodehash[INOHASH(inum)] = np; - diskfs_nref_light (np); -+ rbtree_insert_slot (&nodehash, slot, &dn->tree_node); - nodehash_nr_items += 1; -- - pthread_mutex_unlock (&nodehash_lock); - - /* Get the contents of NP off disk. */ -@@ -149,16 +160,14 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - struct node * - ifind (ino_t inum) - { -- struct node *np; -+ struct rbtree_node *node; - - pthread_mutex_lock (&nodehash_lock); -- for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) -+ node = rbtree_lookup (&nodehash, inum, node_cmp_lookup); -+ if (node != NULL) - { -- if (np->cache_id != inum) -- continue; -- - pthread_mutex_unlock (&nodehash_lock); -- return np; -+ return node_get_np (node); - } - assert (0); - } -@@ -176,7 +185,6 @@ diskfs_node_norefs (struct node *np) - pokel_inherit (&global_pokel, &np->dn->indir_pokel); - pokel_finalize (&np->dn->indir_pokel); - -- free (np->dn); - free (np); - } - -@@ -186,7 +194,7 @@ void - diskfs_try_dropping_softrefs (struct node *np) - { - pthread_mutex_lock (&nodehash_lock); -- if (np->dn->hnext != NULL) -+ if (np->cache_id != 0) - { - /* Check if someone reacquired a reference through the - nodehash. */ -@@ -200,11 +208,9 @@ diskfs_try_dropping_softrefs (struct node *np) - return; - } - -- *np->dn->hprevp = np->dn->hnext; -- if (np->dn->hnext) -- np->dn->hnext->dn->hprevp = np->dn->hprevp; -- np->dn->hnext = NULL; -+ rbtree_remove (&nodehash, &(diskfs_node_disknode (np))->tree_node); - nodehash_nr_items -= 1; -+ np->cache_id = 0; - diskfs_nrele_light (np); - } - pthread_mutex_unlock (&nodehash_lock); -@@ -581,7 +587,7 @@ error_t - diskfs_node_iterate (error_t (*fun)(struct node *)) - { - error_t err = 0; -- int n; -+ struct rbtree_node *n; - size_t num_nodes; - struct node *node, **node_list, **p; - -@@ -605,12 +611,12 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - } - - p = node_list; -- for (n = 0; n < INOHSZ; n++) -- for (node = nodehash[n]; node; node = node->dn->hnext) -- { -- *p++ = node; -- diskfs_nref (node); -- } -+ for (n = rbtree_first (&nodehash); n; n = rbtree_next (n)) -+ { -+ node = node_get_np (n); -+ *p++ = node; -+ diskfs_nref (node); -+ } - - pthread_mutex_unlock (&nodehash_lock); - --- -2.0.0.rc2 - |