diff options
Diffstat (limited to 'debian')
7 files changed, 0 insertions, 1048 deletions
diff --git a/debian/patches/0001-tmpfs-use-a-thread-timeout.patch b/debian/patches/0001-tmpfs-use-a-thread-timeout.patch deleted file mode 100644 index e9aa94c9..00000000 --- a/debian/patches/0001-tmpfs-use-a-thread-timeout.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f1e305fca2b4ca79cfed6d406ceb37f3dfb59f70 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 28 May 2014 16:18:23 +0200 -Subject: [PATCH 1/6] tmpfs: use a thread timeout - -There is no need to keep all the threads around, just the master -thread. - -* tmpfs/tmpfs (diskfs_thread_function): Use a thread timeout. ---- - tmpfs/tmpfs.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c -index a45d343..718c6d8 100644 ---- a/tmpfs/tmpfs.c -+++ b/tmpfs/tmpfs.c -@@ -296,13 +296,14 @@ diskfs_append_args (char **argz, size_t *argz_len) - static void * - diskfs_thread_function (void *demuxer) - { -+ static int thread_timeout = 1000 * 60 * 2; /* two minutes */ - error_t err; - - do - { - ports_manage_port_operations_multithread (diskfs_port_bucket, - (ports_demuxer_type) demuxer, -- 0, -+ thread_timeout, - 0, - 0); - err = diskfs_shutdown (0); --- -2.0.0.rc2 - diff --git a/debian/patches/0002-libnetfs-fix-memory-leak.patch b/debian/patches/0002-libnetfs-fix-memory-leak.patch deleted file mode 100644 index 260c2698..00000000 --- a/debian/patches/0002-libnetfs-fix-memory-leak.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9d8a274e00cf01d2a2ea137f5dbd6f5edb37c15b Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Sat, 31 May 2014 09:16:00 +0200 -Subject: [PATCH 2/6] libnetfs: fix memory leak - -* libnetfs/trans-callback.c (_netfs_translator_callback2_fn): Free -user if creating the protid failed. ---- - libnetfs/trans-callback.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libnetfs/trans-callback.c b/libnetfs/trans-callback.c -index 4dec162..f4f0c62 100644 ---- a/libnetfs/trans-callback.c -+++ b/libnetfs/trans-callback.c -@@ -74,7 +74,10 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, - return 0; - } - else -- return errno; -+ { -+ iohelp_free_iouser (user); -+ return errno; -+ } - } - - fshelp_fetch_root_callback1_t _netfs_translator_callback1 = --- -2.0.0.rc2 - diff --git a/debian/patches/0003-ext2fs-use-a-seperate-lock-to-protect-nodehash.patch b/debian/patches/0003-ext2fs-use-a-seperate-lock-to-protect-nodehash.patch deleted file mode 100644 index e2553b40..00000000 --- a/debian/patches/0003-ext2fs-use-a-seperate-lock-to-protect-nodehash.patch +++ /dev/null @@ -1,207 +0,0 @@ -From a0ce1cfd7c411ac909ce7fa49048b45dcab41758 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 13 May 2014 13:09:15 +0200 -Subject: [PATCH 3/6] ext2fs: use a seperate lock to protect nodehash - -Previously, ext2fs used diskfs_node_refcnt_lock to serialize access to -the nodehash. - -Use a separate lock to protect nodehash. Adjust the reference -counting accordingly. 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. - -* ext2fs/inode.c (nodecache_lock): New lock. -(diskfs_cached_lookup): Use a separate lock to protect nodehash. -Adjust the reference counting accordingly. -(ifind): Likewise. -(diskfs_node_iterate): Likewise. -(diskfs_node_norefs): Move the code removing the node from nodehash... -(diskfs_try_dropping_softrefs): ... here, where we check whether -someone reacquired a reference, and if so hold on to our light -reference. ---- - ext2fs/inode.c | 80 ++++++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 58 insertions(+), 22 deletions(-) - -diff --git a/ext2fs/inode.c b/ext2fs/inode.c -index ed78265..6e46f2b 100644 ---- a/ext2fs/inode.c -+++ b/ext2fs/inode.c -@@ -46,8 +46,18 @@ - #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); - -@@ -71,24 +81,22 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - struct node *np; - struct disknode *dn; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - if (np->cache_id == inum) - { -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref (np); -+ pthread_rwlock_unlock (&nodecache_lock); - pthread_mutex_lock (&np->lock); - *npp = np; - return 0; - } -+ pthread_rwlock_unlock (&nodecache_lock); - - /* Format specific data for the new node. */ - dn = malloc (sizeof (struct disknode)); - if (! dn) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- return ENOMEM; -- } -+ return ENOMEM; - dn->dirents = 0; - dn->dir_idx = 0; - dn->pager = 0; -@@ -102,14 +110,15 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - pthread_mutex_lock (&np->lock); - - /* Put NP in NODEHASH. */ -+ pthread_rwlock_wrlock (&nodecache_lock); - 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); - nodehash_nr_items += 1; -- -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - - /* Get the contents of NP off disk. */ - err = read_node (np); -@@ -140,14 +149,13 @@ ifind (ino_t inum) - { - struct node *np; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - { - if (np->cache_id != inum) - continue; - -- assert (np->references); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - return np; - } - assert (0); -@@ -158,11 +166,6 @@ ifind (ino_t inum) - void - diskfs_node_norefs (struct node *np) - { -- *np->dn->hprevp = np->dn->hnext; -- if (np->dn->hnext) -- np->dn->hnext->dn->hprevp = np->dn->hprevp; -- nodehash_nr_items -= 1; -- - if (np->dn->dirents) - free (np->dn->dirents); - assert (!np->dn->pager); -@@ -180,6 +183,35 @@ diskfs_node_norefs (struct node *np) - void - diskfs_try_dropping_softrefs (struct node *np) - { -+ pthread_rwlock_wrlock (&nodecache_lock); -+ if (np->dn->hnext != NULL) -+ { -+ /* Check if someone reacquired a reference through the -+ nodehash. */ -+ unsigned int references; -+ pthread_spin_lock (&diskfs_node_refcnt_lock); -+ references = np->references; -+ pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ -+ /* An additional reference is acquired by libdiskfs across calls -+ to diskfs_try_dropping_softrefs. */ -+ if (references > 1) -+ { -+ /* 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->dn->hprevp = np->dn->hnext; -+ if (np->dn->hnext) -+ np->dn->hnext->dn->hprevp = np->dn->hprevp; -+ np->dn->hnext = NULL; -+ nodehash_nr_items -= 1; -+ diskfs_nrele_light (np); -+ } -+ pthread_rwlock_unlock (&nodecache_lock); -+ - drop_pager_softrefs (np); - } - -@@ -556,12 +588,12 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - size_t num_nodes; - struct node *node, **node_list, **p; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ 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 -- diskfs_node_refcnt_lock, but we can't hold this while locking the -+ nodecache_lock, but we can't hold this while locking the - individual node locks). */ - num_nodes = nodehash_nr_items; - -@@ -570,7 +602,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - node_list = malloc (num_nodes * sizeof (struct node *)); - if (node_list == NULL) - { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - ext2_debug ("unable to allocate temporary node table"); - return ENOMEM; - } -@@ -580,10 +612,14 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - for (node = nodehash[n]; node; node = node->dn->hnext) - { - *p++ = node; -- node->references++; -+ -+ /* We acquire a hard reference for node, but without using -+ diskfs_nref. We do this so that diskfs_new_hardrefs will not -+ get called. */ -+ node->references++; - } - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - - p = node_list; - while (num_nodes-- > 0) --- -2.0.0.rc2 - diff --git a/debian/patches/0004-fatfs-use-a-seperate-lock-to-protect-nodehash.patch b/debian/patches/0004-fatfs-use-a-seperate-lock-to-protect-nodehash.patch deleted file mode 100644 index 97f4a585..00000000 --- a/debian/patches/0004-fatfs-use-a-seperate-lock-to-protect-nodehash.patch +++ /dev/null @@ -1,249 +0,0 @@ -From cc5be07ba485add1691fbfea1ffd4ee05a1442da Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 13 May 2014 15:14:53 +0200 -Subject: [PATCH 4/6] fatfs: use a seperate lock to protect nodehash - -Previously, fatfs used diskfs_node_refcnt_lock to serialize access to -the nodehash. - -Use a separate lock to protect nodehash. Adjust the reference -counting accordingly. 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. - -* fatfs/inode.c (nodecache_lock): New lock. -(diskfs_cached_lookup): Use a separate lock to protect nodehash. -Adjust the reference counting accordingly. -(ifind): Likewise. -(diskfs_node_iterate): Likewise. -(diskfs_node_norefs): Move the code removing the node from nodehash... -(diskfs_try_dropping_softrefs): ... here, where we check whether -someone reacquired a reference, and if so hold on to our light -reference. ---- - fatfs/inode.c | 95 +++++++++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 66 insertions(+), 29 deletions(-) - -diff --git a/fatfs/inode.c b/fatfs/inode.c -index ed6f3f0..627228c 100644 ---- a/fatfs/inode.c -+++ b/fatfs/inode.c -@@ -44,8 +44,18 @@ - #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, vm_address_t buf); - -@@ -67,24 +77,23 @@ diskfs_cached_lookup (ino64_t inum, struct node **npp) - struct node *np; - struct disknode *dn; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - if (np->cache_id == inum) - { -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref (np); -+ pthread_rwlock_unlock (&nodecache_lock); - pthread_mutex_lock (&np->lock); - *npp = np; - return 0; - } -+ pthread_rwlock_unlock (&nodecache_lock); - - /* Format specific data for the new node. */ - dn = malloc (sizeof (struct disknode)); - if (! dn) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- return ENOMEM; -- } -+ return ENOMEM; -+ - dn->pager = 0; - dn->first = 0; - dn->last = 0; -@@ -102,15 +111,16 @@ diskfs_cached_lookup (ino64_t inum, struct node **npp) - pthread_mutex_lock (&np->lock); - - /* Put NP in NODEHASH. */ -+ pthread_rwlock_wrlock (&nodecache_lock); - 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); - nodehash_nr_items += 1; -+ pthread_rwlock_unlock (&nodecache_lock); - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- - /* Get the contents of NP off disk. */ - err = read_node (np, 0); - -@@ -133,24 +143,23 @@ diskfs_cached_lookup_in_dirbuf (int inum, struct node **npp, vm_address_t buf) - struct node *np; - struct disknode *dn; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - if (np->cache_id == inum) - { -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref (np); -+ pthread_rwlock_unlock (&nodecache_lock); - pthread_mutex_lock (&np->lock); - *npp = np; - return 0; - } -+ pthread_rwlock_unlock (&nodecache_lock); - - /* Format specific data for the new node. */ - dn = malloc (sizeof (struct disknode)); - if (! dn) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- return ENOMEM; -- } -+ return ENOMEM; -+ - dn->pager = 0; - dn->first = 0; - dn->last = 0; -@@ -168,15 +177,16 @@ diskfs_cached_lookup_in_dirbuf (int inum, struct node **npp, vm_address_t buf) - pthread_mutex_lock (&np->lock); - - /* Put NP in NODEHASH. */ -+ pthread_rwlock_wrlock (&nodecache_lock); - 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); - nodehash_nr_items += 1; -+ pthread_rwlock_unlock (&nodecache_lock); - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- - /* Get the contents of NP off disk. */ - err = read_node (np, buf); - -@@ -196,14 +206,13 @@ ifind (ino_t inum) - { - struct node *np; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - { - if (np->cache_id != inum) - continue; - -- assert (np->references); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - return np; - } - assert (0); -@@ -216,11 +225,6 @@ diskfs_node_norefs (struct node *np) - { - struct cluster_chain *last = np->dn->first; - -- *np->dn->hprevp = np->dn->hnext; -- if (np->dn->hnext) -- np->dn->hnext->dn->hprevp = np->dn->hprevp; -- nodehash_nr_items -= 1; -- - while (last) - { - struct cluster_chain *next = last->next; -@@ -251,6 +255,35 @@ diskfs_node_norefs (struct node *np) - void - diskfs_try_dropping_softrefs (struct node *np) - { -+ pthread_rwlock_wrlock (&nodecache_lock); -+ if (np->dn->hnext != NULL) -+ { -+ /* Check if someone reacquired a reference through the -+ nodehash. */ -+ unsigned int references; -+ pthread_spin_lock (&diskfs_node_refcnt_lock); -+ references = np->references; -+ pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ -+ /* An additional reference is acquired by libdiskfs across calls -+ to diskfs_try_dropping_softrefs. */ -+ if (references > 1) -+ { -+ /* 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->dn->hprevp = np->dn->hnext; -+ if (np->dn->hnext) -+ np->dn->hnext->dn->hprevp = np->dn->hprevp; -+ np->dn->hnext = NULL; -+ nodehash_nr_items -= 1; -+ diskfs_nrele_light (np); -+ } -+ pthread_rwlock_unlock (&nodecache_lock); -+ - drop_pager_softrefs (np); - } - -@@ -554,12 +587,12 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - size_t num_nodes; - struct node *node, **node_list, **p; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ 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 -- diskfs_node_refcnt_lock, but we can't hold this while locking the -+ nodecache_lock, but we can't hold this while locking the - individual node locks). */ - - num_nodes = nodehash_nr_items; -@@ -570,10 +603,14 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - for (node = nodehash[n]; node; node = node->dn->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. */ - node->references++; - } - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - - p = node_list; - while (num_nodes-- > 0) --- -2.0.0.rc2 - diff --git a/debian/patches/0005-isofs-use-a-seperate-lock-to-protect-node_cache.patch b/debian/patches/0005-isofs-use-a-seperate-lock-to-protect-node_cache.patch deleted file mode 100644 index f9171fc1..00000000 --- a/debian/patches/0005-isofs-use-a-seperate-lock-to-protect-node_cache.patch +++ /dev/null @@ -1,231 +0,0 @@ -From d1a6f1289f3d8c0725cc0eb2713b909b5a9776a0 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 13 May 2014 15:16:31 +0200 -Subject: [PATCH 5/6] isofs: use a seperate lock to protect node_cache - -Previously, isofs used diskfs_node_refcnt_lock to serialize access to -the node_cache. - -Use a separate lock to protect node_cache. Adjust the reference -counting accordingly. Every node in the node_cache 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 node_cache. - -* isofs/inode.c (nodecache_lock): New lock. -(inode_cache_find): Use a separate lock to protect node_cache. -Adjust the reference counting accordingly. -(diskfs_cached_lookup): Likewise. -(load_inode): Likewise. -(cache_inode): Update comment accordingly. -(diskfs_node_iterate): Likewise. -(diskfs_node_norefs): Move the code removing the node from node_cache... -(diskfs_try_dropping_softrefs): ... here, where we check whether -someone reacquired a reference, and if so hold on to our light -reference. ---- - isofs/inode.c | 83 +++++++++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 58 insertions(+), 25 deletions(-) - -diff --git a/isofs/inode.c b/isofs/inode.c -index cdc05ae..9fabb0d 100644 ---- a/isofs/inode.c -+++ b/isofs/inode.c -@@ -48,9 +48,19 @@ struct node_cache - struct node *np; /* if live */ - }; - -+/* The node_cache is a cache of nodes. -+ -+ Access to node_cache, node_cache_size, and node_cache_alloced is -+ protected by nodecache_lock. -+ -+ Every node in the node_cache 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 node_cache. */ - static int node_cache_size = 0; - static int node_cache_alloced = 0; - struct node_cache *node_cache = 0; -+static pthread_rwlock_t nodecache_lock = PTHREAD_RWLOCK_INITIALIZER; - - /* Forward */ - static error_t read_disknode (struct node *, -@@ -58,7 +68,7 @@ static error_t read_disknode (struct node *, - - - /* See if node with identifier ID is in the cache. If so, return it, -- with one additional reference. diskfs_node_refcnt_lock must be held -+ with one additional reference. nodecache_lock must be held - on entry to the call, and will be released iff the node was found - in the cache. */ - void -@@ -71,8 +81,8 @@ inode_cache_find (off_t id, struct node **npp) - && node_cache[i].np) - { - *npp = node_cache[i].np; -- (*npp)->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref (*npp); -+ pthread_rwlock_unlock (&nodecache_lock); - pthread_mutex_lock (&(*npp)->lock); - return; - } -@@ -92,7 +102,7 @@ use_file_start_id (struct dirrect *record, struct rrip_lookup *rr) - } - - /* Enter NP into the cache. The directory entry we used is DR, the -- cached Rock-Ridge info RR. diskfs_node_refcnt_lock must be held. */ -+ cached Rock-Ridge info RR. nodecache_lock must be held. */ - void - cache_inode (struct node *np, struct dirrect *record, - struct rrip_lookup *rr) -@@ -155,7 +165,7 @@ diskfs_cached_lookup (ino_t id, struct node **npp) - to avoid presenting zero cache ID's. */ - id--; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - assert (id < node_cache_size); - - np = node_cache[id].np; -@@ -174,7 +184,7 @@ diskfs_cached_lookup (ino_t id, struct node **npp) - dn = malloc (sizeof (struct disknode)); - if (!dn) - { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - release_rrip (&rr); - return ENOMEM; - } -@@ -185,16 +195,17 @@ diskfs_cached_lookup (ino_t id, struct node **npp) - if (!np) - { - free (dn); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - release_rrip (&rr); - return ENOMEM; - } - np->cache_id = id + 1; /* see above for rationale for increment */ - pthread_mutex_lock (&np->lock); - c->np = np; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref_light (np); -+ pthread_rwlock_unlock (&nodecache_lock); - -- err = read_disknode (np, node_cache[id].dr, &rr); -+ err = read_disknode (np, dn->dr, &rr); - if (!err) - *npp = np; - -@@ -204,8 +215,8 @@ diskfs_cached_lookup (ino_t id, struct node **npp) - } - - -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref (np); -+ pthread_rwlock_unlock (&nodecache_lock); - pthread_mutex_lock (&np->lock); - *npp = np; - return 0; -@@ -315,7 +326,7 @@ load_inode (struct node **npp, struct dirrect *record, - if (rr->valid & VALID_CL) - record = rr->realdirent; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&nodecache_lock); - - /* First check the cache */ - if (use_file_start_id (record, rr)) -@@ -323,19 +334,16 @@ load_inode (struct node **npp, struct dirrect *record, - else - inode_cache_find ((off_t) ((void *) record - (void *) disk_image), npp); - -+ pthread_rwlock_unlock (&nodecache_lock); -+ - if (*npp) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- return 0; -- } -+ return 0; - - /* Create a new node */ - dn = malloc (sizeof (struct disknode)); - if (!dn) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- return ENOMEM; -- } -+ return ENOMEM; -+ - dn->fileinfo = 0; - dn->dr = record; - dn->file_start = file_start; -@@ -344,14 +352,14 @@ load_inode (struct node **npp, struct dirrect *record, - if (!np) - { - free (dn); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); - return ENOMEM; - } - - pthread_mutex_lock (&np->lock); - -+ pthread_rwlock_wrlock (&nodecache_lock); - cache_inode (np, record, rr); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&nodecache_lock); - - err = read_disknode (np, record, rr); - *npp = np; -@@ -505,9 +513,6 @@ error_t (*diskfs_read_symlink_hook) (struct node *, char *) - void - diskfs_node_norefs (struct node *np) - { -- assert (node_cache[np->cache_id - 1].np == np); -- node_cache[np->cache_id - 1].np = 0; -- - if (np->dn->translator) - free (np->dn->translator); - -@@ -521,6 +526,34 @@ diskfs_node_norefs (struct node *np) - void - diskfs_try_dropping_softrefs (struct node *np) - { -+ pthread_rwlock_wrlock (&nodecache_lock); -+ if (np->cache_id != 0) -+ { -+ assert (node_cache[np->cache_id - 1].np == np); -+ -+ /* Check if someone reacquired a reference through the -+ node_cache. */ -+ unsigned int references; -+ pthread_spin_lock (&diskfs_node_refcnt_lock); -+ references = np->references; -+ pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ -+ /* An additional reference is acquired by libdiskfs across calls -+ to diskfs_try_dropping_softrefs. */ -+ if (references > 1) -+ { -+ /* A reference was reacquired through a hash table lookup. -+ It's fine, we didn't touch anything yet. */ -+ pthread_rwlock_unlock (&nodecache_lock); -+ return; -+ } -+ -+ node_cache[np->cache_id - 1].np = 0; -+ np->cache_id = 0; -+ diskfs_nrele_light (np); -+ } -+ pthread_rwlock_unlock (&nodecache_lock); -+ - drop_pager_softrefs (np); - } - --- -2.0.0.rc2 - diff --git a/debian/patches/0006-tmpfs-use-a-seperate-lock-to-protect-all_nodes.patch b/debian/patches/0006-tmpfs-use-a-seperate-lock-to-protect-all_nodes.patch deleted file mode 100644 index 22957ece..00000000 --- a/debian/patches/0006-tmpfs-use-a-seperate-lock-to-protect-all_nodes.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 10b27d8a93bd689f775213fe2e0a78bb68496c12 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 13 May 2014 15:35:42 +0200 -Subject: [PATCH 6/6] tmpfs: use a seperate lock to protect all_nodes - -Previously, tmpfs used diskfs_node_refcnt_lock to serialize access to -the all_nodes and some other related global state related to memory -consumption. - -Use a separate lock to protect all_nodes, and atomic operations to -access the state related to memory consumption. Adjust the reference -counting accordingly. Every node in the all_nodes 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 all_nodes. - -* tmpfs/tmpfs.h (num_files, tmpfs_space_used): Use atomic operations -for these variables. -(adjust_used): Use atomic operations. -(get_used): New convenience function to atomically retrieve -tmpfs_space_used. -* tmpfs/node.c (all_nodes_lock): New lock. -(diskfs_alloc_node): Use a separate lock to protect all_nodes. -Adjust the reference counting accordingly. -(diskfs_free_node): Likewise. -(diskfs_cached_lookup):Likewise. -(diskfs_node_iterate): Likewise. -(diskfs_node_norefs): Do not remove the node from all_nodes. This -actually looks like a mistake, I do not know why they did that here as -well as in diskfs_free_node. -(diskfs_try_dropping_softrefs): Check whether someone reacquired a -reference, and if so hold on to our light reference. -(diskfs_grow): Use atomic operations. -* tmpfs/tmpfs.c (diskfs_set_statfs): Likewise. ---- - tmpfs/node.c | 83 ++++++++++++++++++++++++++++++++++++++++++----------------- - tmpfs/tmpfs.c | 6 ++--- - tmpfs/tmpfs.h | 20 +++++++++----- - 3 files changed, 76 insertions(+), 33 deletions(-) - -diff --git a/tmpfs/node.c b/tmpfs/node.c -index acc029a..2c0108a 100644 ---- a/tmpfs/node.c -+++ b/tmpfs/node.c -@@ -29,8 +29,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - unsigned int num_files; - static unsigned int gen; - -+/* all_nodes is a list of all nodes. -+ -+ Access to all_nodes and all_nodes_nr_items is protected by -+ all_nodes_lock. -+ -+ Every node in all_nodes 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. */ - struct node *all_nodes; - static size_t all_nodes_nr_items; -+pthread_rwlock_t all_nodes_lock = PTHREAD_RWLOCK_INITIALIZER; - - error_t - diskfs_alloc_node (struct node *dp, mode_t mode, struct node **npp) -@@ -40,18 +50,17 @@ diskfs_alloc_node (struct node *dp, mode_t mode, struct node **npp) - dn = calloc (1, sizeof *dn); - if (dn == 0) - return ENOSPC; -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- if (round_page (tmpfs_space_used + sizeof *dn) / vm_page_size -+ -+ if (round_page (get_used () + sizeof *dn) / vm_page_size - > tmpfs_page_limit) - { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&all_nodes_lock); - free (dn); - return ENOSPC; - } - dn->gen = gen++; -- ++num_files; -- tmpfs_space_used += sizeof *dn; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ __atomic_add_fetch (&num_files, 1, __ATOMIC_RELAXED); -+ adjust_used (sizeof *dn); - - dn->type = IFTODT (mode & S_IFMT); - return diskfs_cached_lookup ((ino_t) (uintptr_t) dn, npp); -@@ -75,15 +84,19 @@ diskfs_free_node (struct node *np, mode_t mode) - free (np->dn->u.lnk); - break; - } -+ -+ pthread_rwlock_wrlock (&all_nodes_lock); - *np->dn->hprevp = np->dn->hnext; - if (np->dn->hnext != 0) - np->dn->hnext->dn->hprevp = np->dn->hprevp; - all_nodes_nr_items -= 1; -+ pthread_rwlock_unlock (&all_nodes_lock); -+ - free (np->dn); - np->dn = 0; - -- --num_files; -- tmpfs_space_used -= sizeof *np->dn; -+ __atomic_sub_fetch (&num_files, 1, __ATOMIC_RELAXED); -+ adjust_used (-sizeof *np->dn); - } - - void -@@ -117,14 +130,6 @@ diskfs_node_norefs (struct node *np) - np->dn->u.chr = np->dn_stat.st_rdev; - break; - } -- -- /* Remove this node from the cache list rooted at `all_nodes'. */ -- *np->dn->hprevp = np->dn->hnext; -- if (np->dn->hnext != 0) -- np->dn->hnext->dn->hprevp = np->dn->hprevp; -- all_nodes_nr_items -= 1; -- np->dn->hnext = 0; -- np->dn->hprevp = 0; - } - - free (np); -@@ -167,30 +172,33 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - - assert (npp); - -+ pthread_rwlock_rdlock (&all_nodes_lock); - if (dn->hprevp != 0) /* There is already a node. */ - { - np = *dn->hprevp; - assert (np->dn == dn); - assert (*dn->hprevp == np); -- - diskfs_nref (np); -+ pthread_rwlock_unlock (&all_nodes_lock); - } - else - /* Create the new node. */ - { - struct stat *st; -+ pthread_rwlock_unlock (&all_nodes_lock); - - np = diskfs_make_node (dn); - np->cache_id = (ino_t) (uintptr_t) dn; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_wrlock (&all_nodes_lock); - dn->hnext = all_nodes; - if (dn->hnext) - dn->hnext->dn->hprevp = &dn->hnext; - dn->hprevp = &all_nodes; - all_nodes = np; - all_nodes_nr_items += 1; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref_light (np); -+ pthread_rwlock_unlock (&all_nodes_lock); - - st = &np->dn_stat; - memset (st, 0, sizeof *st); -@@ -229,12 +237,12 @@ diskfs_node_iterate (error_t (*fun) (struct node *)) - size_t num_nodes; - struct node *node, **node_list, **p; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_rdlock (&all_nodes_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 -- diskfs_node_refcnt_lock, but we can't hold this while locking the -+ all_nodes_lock, but we can't hold this while locking the - individual node locks). */ - - num_nodes = all_nodes_nr_items; -@@ -243,10 +251,14 @@ diskfs_node_iterate (error_t (*fun) (struct node *)) - for (node = all_nodes; node != 0; node = node->dn->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. */ - node->references++; - } - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_rwlock_unlock (&all_nodes_lock); - - p = node_list; - while (num_nodes-- > 0) -@@ -272,6 +284,31 @@ diskfs_node_iterate (error_t (*fun) (struct node *)) - void - diskfs_try_dropping_softrefs (struct node *np) - { -+ pthread_rwlock_wrlock (&all_nodes_lock); -+ if (np->cache_id != 0) -+ { -+ /* Check if someone reacquired a reference. */ -+ unsigned int references; -+ pthread_spin_lock (&diskfs_node_refcnt_lock); -+ references = np->references; -+ pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ -+ /* An additional reference is acquired by libdiskfs across calls -+ to diskfs_try_dropping_softrefs. */ -+ if (references > 1) -+ { -+ /* A reference was reacquired. It's fine, we didn't touch -+ anything yet. */ -+ pthread_rwlock_unlock (&all_nodes_lock); -+ return; -+ } -+ -+ /* Just let go of the weak reference. The node will be removed -+ from all_nodes in diskfs_free_node. */ -+ np->cache_id = 0; -+ diskfs_nrele_light (np); -+ } -+ pthread_rwlock_unlock (&all_nodes_lock); - } - - /* The user must define this funcction. Node NP has some light -@@ -447,7 +484,7 @@ diskfs_grow (struct node *np, off_t size, struct protid *cred) - - off_t set_size = size; - size = round_page (size); -- if (round_page (tmpfs_space_used + size - np->allocsize) -+ if (round_page (get_used () + size - np->allocsize) - / vm_page_size > tmpfs_page_limit) - return ENOSPC; - -diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c -index 718c6d8..0aace25 100644 ---- a/tmpfs/tmpfs.c -+++ b/tmpfs/tmpfs.c -@@ -67,10 +67,8 @@ diskfs_set_statfs (struct statfs *st) - st->f_bsize = vm_page_size; - st->f_blocks = tmpfs_page_limit; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- st->f_files = num_files; -- pages = round_page (tmpfs_space_used) / vm_page_size; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ st->f_files = __atomic_load_n (&num_files, __ATOMIC_RELAXED); -+ pages = round_page (get_used ()) / vm_page_size; - - st->f_bfree = pages < tmpfs_page_limit ? tmpfs_page_limit - pages : 0; - st->f_bavail = st->f_bfree; -diff --git a/tmpfs/tmpfs.h b/tmpfs/tmpfs.h -index b3c636d..ad47200 100644 ---- a/tmpfs/tmpfs.h -+++ b/tmpfs/tmpfs.h -@@ -69,17 +69,25 @@ struct tmpfs_dirent - char name[0]; - }; - --extern unsigned int num_files; --extern off_t tmpfs_page_limit, tmpfs_space_used; -- -+extern off_t tmpfs_page_limit; - extern mach_port_t default_pager; - -+/* These two must be accessed using atomic operations. */ -+extern unsigned int num_files; -+extern off_t tmpfs_space_used; -+ -+/* Convenience function to adjust tmpfs_space_used. */ - static inline void - adjust_used (off_t change) - { -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- tmpfs_space_used += change; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ __atomic_add_fetch (&num_files, change, __ATOMIC_RELAXED); -+} -+ -+/* Convenience function to get tmpfs_space_used. */ -+static inline off_t -+get_used (void) -+{ -+ return __atomic_load_n (&num_files, __ATOMIC_RELAXED); - } - - #endif --- -2.0.0.rc2 - diff --git a/debian/patches/series b/debian/patches/series index 1a09ebce..2d703f80 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -41,9 +41,3 @@ xkb-compat.patch mach-defpager-protected-payload.patch -0001-tmpfs-use-a-thread-timeout.patch -0002-libnetfs-fix-memory-leak.patch -0003-ext2fs-use-a-seperate-lock-to-protect-nodehash.patch -0004-fatfs-use-a-seperate-lock-to-protect-nodehash.patch -0005-isofs-use-a-seperate-lock-to-protect-node_cache.patch -0006-tmpfs-use-a-seperate-lock-to-protect-all_nodes.patch |