summaryrefslogtreecommitdiff
path: root/debian/patches/0016-xxx-fatfs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0016-xxx-fatfs.patch')
-rw-r--r--debian/patches/0016-xxx-fatfs.patch460
1 files changed, 460 insertions, 0 deletions
diff --git a/debian/patches/0016-xxx-fatfs.patch b/debian/patches/0016-xxx-fatfs.patch
new file mode 100644
index 00000000..c8a25de3
--- /dev/null
+++ b/debian/patches/0016-xxx-fatfs.patch
@@ -0,0 +1,460 @@
+From b3f0189145afa4efe38335043213b89e72ff99f3 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Thu, 16 Apr 2015 16:12:05 +0200
+Subject: [PATCH hurd 16/16] xxx fatfs
+
+---
+ fatfs/dir.c | 6 +-
+ fatfs/fatfs.h | 14 ++-
+ fatfs/inode.c | 284 +++++-----------------------------------------------------
+ 3 files changed, 37 insertions(+), 267 deletions(-)
+
+diff --git a/fatfs/dir.c b/fatfs/dir.c
+index 5a38c63..9eea74c 100644
+--- a/fatfs/dir.c
++++ b/fatfs/dir.c
+@@ -342,7 +342,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)
+ {
+@@ -395,7 +395,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)
+@@ -732,7 +732,7 @@ diskfs_dirrewrite_hard (struct node *dp, struct node *np, struct dirstat *ds)
+ assert (err != EINVAL);
+
+ /* Lookup the node, we already have a reference. */
+- oldnp = ifind (inode);
++ oldnp = diskfs_cached_ifind (inode);
+
+ assert (ds->type == RENAME);
+ assert (ds->stat == HERE_TIS);
+diff --git a/fatfs/fatfs.h b/fatfs/fatfs.h
+index 9d38546..be4ad42 100644
+--- a/fatfs/fatfs.h
++++ b/fatfs/fatfs.h
+@@ -71,6 +71,18 @@ struct disknode
+ int dir_idx;
+ };
+
++struct lookup_context
++{
++ /* The inode as returned by virtual inode management routines. */
++ inode_t inode;
++
++ /* xxx */
++ vm_address_t buf;
++
++ /* xxx */
++ struct node *dir;
++};
++
+ struct user_pager_info
+ {
+ struct node *node;
+@@ -117,8 +129,6 @@ void flush_node_pager (struct node *node);
+
+ void write_all_disknodes ();
+
+-struct node *ifind (ino_t inum);
+-
+ error_t fat_get_next_cluster (cluster_t cluster, cluster_t *next_cluster);
+ void fat_to_unix_filename (const char *, char *);
+
+diff --git a/fatfs/inode.c b/fatfs/inode.c
+index f228618..8b41238 100644
+--- a/fatfs/inode.c
++++ b/fatfs/inode.c
+@@ -37,69 +37,20 @@
+ #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
+- 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);
+-
+-/* 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 = np->dn->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 (ino64_t inum, struct node **npp)
++diskfs_user_make_node (struct node **npp, struct lookup_context *ctx)
+ {
+- 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);
+-
+- /* Format specific data for the new node. */
+- dn = malloc (sizeof (struct disknode));
+- if (! dn)
++ /* Create the new node. */
++ np = diskfs_make_node_alloc (sizeof *dn);
++ if (np == NULL)
+ return ENOMEM;
+
++ /* Format specific data for the new node. */
++ dn = diskfs_node_disknode (np);
+ dn->pager = 0;
+ dn->first = 0;
+ dn->last = 0;
+@@ -108,50 +59,9 @@ diskfs_cached_lookup (ino64_t inum, struct node **npp)
+ dn->chain_extension_lock = PTHREAD_SPINLOCK_INITIALIZER;
+ pthread_rwlock_init (&dn->alloc_lock, NULL);
+ pthread_rwlock_init (&dn->dirent_lock, NULL);
+-
+- /* Create the new node. */
+- np = diskfs_make_node (dn);
+- np->cache_id = inum;
+- np->dn->inode = vi_lookup(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;
+- }
+-
+- 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);
+-
+- /* Get the contents of NP off disk. */
+- err = read_node (np, 0);
+-
+- 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;
++ np->dn->inode = ctx->inode;
++ np->dn->dirnode = ctx->dir;
+ return 0;
+ }
+
+@@ -162,78 +72,8 @@ error_t
+ diskfs_cached_lookup_in_dirbuf (int inum, struct node **npp, vm_address_t buf)
+ {
+ error_t err;
+- struct node *np;
+- struct disknode *dn;
+-
+- pthread_rwlock_rdlock (&nodecache_lock);
+- for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext)
+- if (np->cache_id == inum)
+- {
+- 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)
+- return ENOMEM;
+-
+- dn->pager = 0;
+- dn->first = 0;
+- dn->last = 0;
+- dn->length_of_chain = 0;
+- dn->chain_complete = 0;
+- dn->chain_extension_lock = PTHREAD_SPINLOCK_INITIALIZER;
+- pthread_rwlock_init (&dn->alloc_lock, NULL);
+- pthread_rwlock_init (&dn->dirent_lock, NULL);
+-
+- /* Create the new node. */
+- np = diskfs_make_node (dn);
+- np->cache_id = inum;
+- np->dn->inode = vi_lookup(inum);
+-
+- 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);
+-
+- /* Get the contents of NP off disk. */
+- err = read_node (np, buf);
+-
+- if (err)
+- return err;
+- else
+- {
+- *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;
++ struct lookup_context ctx = { buf: buf };
++ return diskfs_cached_lookup_context (inum, npp, &ctx);
+ }
+
+ /* The last reference to a node has gone away; drop it from the hash
+@@ -258,41 +98,14 @@ diskfs_node_norefs (struct node *np)
+
+ assert (!np->dn->pager);
+
+- free (np->dn);
+ free (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 (np->dn->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->dn->hprevp = np->dn->hnext;
+- if (np->dn->hnext)
+- np->dn->hnext->dn->hprevp = np->dn->hprevp;
+- np->dn->hnext = NULL;
+- np->dn->hprevp = NULL;
+- nodehash_nr_items -= 1;
+- diskfs_nrele_light (np);
+- }
+- pthread_rwlock_unlock (&nodecache_lock);
+-
+ drop_pager_softrefs (np);
+ }
+
+@@ -311,8 +124,8 @@ diskfs_new_hardrefs (struct node *np)
+ }
+
+ /* Read stat information out of the directory entry. */
+-static error_t
+-read_node (struct node *np, vm_address_t buf)
++error_t
++diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
+ {
+ /* XXX This needs careful investigation. */
+ error_t err;
+@@ -323,6 +136,7 @@ read_node (struct node *np, vm_address_t buf)
+ struct vi_key vk = vi_key(np->dn->inode);
+ vm_prot_t prot = VM_PROT_READ;
+ memory_object_t memobj;
++ vm_address_t buf = ctx->buf;
+ vm_size_t buflen = 0;
+ int our_buf = 0;
+
+@@ -359,7 +173,7 @@ read_node (struct node *np, vm_address_t buf)
+ /* FIXME: We know intimately that the parent dir is locked
+ by libdiskfs. The only case it is not locked is for NFS
+ (fsys_getfile) and we disabled that. */
+- dp = ifind (vk.dir_inode);
++ dp = diskfs_cached_ifind (vk.dir_inode);
+ assert (dp);
+
+ /* Map in the directory contents. */
+@@ -572,7 +386,7 @@ error_t
+ diskfs_node_reload (struct node *node)
+ {
+ struct cluster_chain *last = node->dn->first;
+-
++ static struct lookup_context ctx = { buf: 0 };
+ while (last)
+ {
+ struct cluster_chain *next = last->next;
+@@ -580,61 +394,8 @@ diskfs_node_reload (struct node *node)
+ last = next;
+ }
+ flush_node_pager (node);
+- read_node (node, 0);
+
+- 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;
+-
+- node_list = alloca (num_nodes * sizeof (struct node *));
+- p = node_list;
+- for (n = 0; n < INOHSZ; n++)
+- 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. */
+- 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);
+- }
+-
+- return err;
++ return diskfs_user_read_node (node, &ctx);
+ }
+
+ /* Write all active disknodes into the ext2_inode pager. */
+@@ -812,7 +573,8 @@ diskfs_alloc_node (struct node *dir, mode_t mode, struct node **node)
+ ino_t inum;
+ inode_t inode;
+ struct node *np;
+-
++ struct lookup_context ctx = { dir: dir };
++
+ assert (!diskfs_readonly);
+
+ /* FIXME: We use a magic key here that signals read_node that we are
+@@ -821,12 +583,10 @@ diskfs_alloc_node (struct node *dir, mode_t mode, struct node **node)
+ if (err)
+ return err;
+
+- err = diskfs_cached_lookup (inum, &np);
++ err = diskfs_cached_lookup_context (inum, &np, &ctx);
+ if (err)
+ return err;
+
+- /* FIXME: We know that readnode couldn't put this in. */
+- np->dn->dirnode = dir;
+ refcounts_ref (&dir->refcounts, NULL);
+
+ *node = np;
+--
+2.1.4
+