summaryrefslogtreecommitdiff
path: root/debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-04-17 14:17:23 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-04-17 14:17:23 +0200
commit7f240848cb840544124d08b1a317309d6dc9107e (patch)
tree1c7eddb9fd1aba2f8822d6f1f1e8b2b07e858ca5 /debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch
parentcc37b9eaebce8c8f2b7c00607c7cac5e7eda6a27 (diff)
add patch series
Diffstat (limited to 'debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch')
-rw-r--r--debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch573
1 files changed, 573 insertions, 0 deletions
diff --git a/debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch b/debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch
new file mode 100644
index 00000000..d32cc611
--- /dev/null
+++ b/debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch
@@ -0,0 +1,573 @@
+From ce2f7cbea4f72e01eb7a6c112f1462137b9b8d84 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Wed, 15 Apr 2015 16:26:31 +0200
+Subject: [PATCH hurd 12/13] isofs: port to libdiskfs' node cache
+
+---
+ isofs/inode.c | 314 ++++++---------------------------------------------------
+ isofs/isofs.h | 9 ++
+ isofs/lookup.c | 18 ++--
+ isofs/main.c | 15 +--
+ isofs/rr.c | 4 +
+ 5 files changed, 63 insertions(+), 297 deletions(-)
+
+diff --git a/isofs/inode.c b/isofs/inode.c
+index e79ebdd..5163df5 100644
+--- a/isofs/inode.c
++++ b/isofs/inode.c
+@@ -31,72 +31,6 @@
+ record for symlinks and zero length files, and file_start otherwise.
+ Only for hard links to zero length files we get extra inodes. */
+
+-#define INOHSZ 512
+-#if ((INOHSZ&(INOHSZ-1)) == 0)
+-#define INOHASH(ino) ((ino>>8)&(INOHSZ-1))
+-#else
+-#define INOHASH(ino) (((unsigned)(ino>>8))%INOHSZ)
+-#endif
+-
+-struct node_cache
+-{
+- struct dirrect *dr; /* somewhere in disk_image */
+- off_t file_start; /* start of file */
+-
+- off_t id; /* UNIQUE identifier. */
+-
+- 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 *,
+- struct dirrect *, struct rrip_lookup *);
+-
+-
+-/* Lookup node with id ID. Returns NULL if the node is not found in
+- the node cache. */
+-static struct node *
+-lookup (off_t id)
+-{
+- int i;
+- for (i = 0; i < node_cache_size; i++)
+- if (node_cache[i].id == id
+- && node_cache[i].np)
+- return node_cache[i].np;
+- return NULL;
+-}
+-
+-/* See if node with identifier ID is in the cache. If so, return it,
+- 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
+-inode_cache_find (off_t id, struct node **npp)
+-{
+- *npp = lookup (id);
+- if (*npp)
+- {
+- diskfs_nref (*npp);
+- pthread_rwlock_unlock (&nodecache_lock);
+- pthread_mutex_lock (&(*npp)->lock);
+- }
+-}
+-
+-
+ /* Determine if we use file_start or struct dirrect * as node id. */
+ int
+ use_file_start_id (struct dirrect *record, struct rrip_lookup *rr)
+@@ -108,140 +42,34 @@ use_file_start_id (struct dirrect *record, struct rrip_lookup *rr)
+ return 1;
+ }
+
+-/* Enter NP into the cache. The directory entry we used is DR, the
+- cached Rock-Ridge info RR. nodecache_lock must be held. */
+-void
+-cache_inode (struct node *np, struct dirrect *record,
+- struct rrip_lookup *rr)
+-{
+- int i;
+- struct node_cache *c = 0;
+- off_t id;
+-
+- if (use_file_start_id (record, rr))
+- id = np->dn->file_start << store->log2_block_size;
+- else
+- id = (off_t) ((void *) record - (void *) disk_image);
+-
+- /* First see if there's already an entry. */
+- for (i = 0; i < node_cache_size; i++)
+- if (node_cache[i].id == id)
+- break;
+-
+- if (i == node_cache_size)
+- {
+- if (node_cache_size >= node_cache_alloced)
+- {
+- if (!node_cache_alloced)
+- {
+- /* Initialize */
+- node_cache_alloced = 10;
+- node_cache = malloc (sizeof (struct node_cache) * 10);
+- }
+- else
+- {
+- node_cache_alloced *= 2;
+- node_cache = realloc (node_cache,
+- sizeof (struct node_cache)
+- * node_cache_alloced);
+- }
+- assert (node_cache);
+- }
+- node_cache_size++;
+- }
+-
+- c = &node_cache[i];
+- c->id = id;
+- c->dr = record;
+- c->file_start = np->dn->file_start;
+- diskfs_nref_light (np);
+- c->np = np;
+-
+- /* PLUS 1 so that we don't store zero cache ID's (not allowed by diskfs) */
+- np->cache_id = i + 1;
+-}
+-
+-/* Fetch inode with cache id ID; set *NPP to the node structure;
+- gain one user reference and lock the node. */
++/* XXX */
+ error_t
+-diskfs_cached_lookup (ino_t id, struct node **npp)
++diskfs_user_make_node (struct node **npp, struct lookup_context *ctx)
+ {
+- struct node *np;
+ error_t err;
++ struct node *np;
++ struct disknode *dn;
+
+- /* Cache ID's are incremented when presented to diskfs
+- to avoid presenting zero cache ID's. */
+- id--;
+-
+- pthread_rwlock_rdlock (&nodecache_lock);
+- assert (id < node_cache_size);
+-
+- np = node_cache[id].np;
++ /* Create the new node. */
++ np = diskfs_make_node_alloc (sizeof *dn);
++ if (np == NULL)
++ return ENOMEM;
+
+- if (!np)
++ /* Format specific data for the new node. */
++ dn = diskfs_node_disknode (np);
++ dn->fileinfo = 0;
++ dn->dr = ctx->dr;
++ err = calculate_file_start (ctx->dr, &dn->file_start, &ctx->rr);
++ if (err)
+ {
+- struct node_cache *c = &node_cache[id];
+- struct rrip_lookup rr;
+- struct disknode *dn;
+-
+- pthread_rwlock_unlock (&nodecache_lock);
+-
+- rrip_lookup (node_cache[id].dr, &rr, 1);
+-
+- /* We should never cache the wrong directory entry */
+- assert (!(rr.valid & VALID_CL));
+-
+- dn = malloc (sizeof (struct disknode));
+- if (!dn)
+- {
+- pthread_rwlock_unlock (&nodecache_lock);
+- release_rrip (&rr);
+- return ENOMEM;
+- }
+- dn->fileinfo = 0;
+- dn->dr = c->dr;
+- dn->file_start = c->file_start;
+- np = diskfs_make_node (dn);
+- if (!np)
+- {
+- free (dn);
+- 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);
+-
+- pthread_rwlock_wrlock (&nodecache_lock);
+- if (c->np != NULL)
+- {
+- /* We lost a race. */
+- diskfs_nput (np);
+- np = c->np;
+- goto gotit;
+- }
+- c->np = np;
+- diskfs_nref_light (np);
+- pthread_rwlock_unlock (&nodecache_lock);
+-
+- err = read_disknode (np, dn->dr, &rr);
+- if (!err)
+- *npp = np;
+-
+- release_rrip (&rr);
+-
++ diskfs_nrele (np);
+ return err;
+ }
+
+- gotit:
+- diskfs_nref (np);
+- pthread_rwlock_unlock (&nodecache_lock);
+- pthread_mutex_lock (&np->lock);
+ *npp = np;
+ return 0;
+ }
+
+-
+ /* Return Epoch-based time from a seven byte according to 9.1.5 */
+ char *
+ isodate_915 (char *c, struct timespec *ts)
+@@ -315,6 +143,9 @@ calculate_file_start (struct dirrect *record, off_t *file_start,
+ *file_start = rr->realfilestart;
+ else
+ {
++ if (record == NULL)
++ return ENOENT;
++
+ err = diskfs_catch_exception ();
+ if (err)
+ return err;
+@@ -327,90 +158,38 @@ calculate_file_start (struct dirrect *record, off_t *file_start,
+ return 0;
+ }
+
+-
+-/* Load the inode with directory entry RECORD and cached Rock-Ridge
+- info RR into NP. The directory entry is at OFFSET in BLOCK. */
++/* Given RECORD and RR, calculate the cache id. */
+ error_t
+-load_inode (struct node **npp, struct dirrect *record,
+- struct rrip_lookup *rr)
++cache_id (struct dirrect *record, struct rrip_lookup *rr, ino_t *idp)
+ {
+ error_t err;
+ off_t file_start;
+- struct disknode *dn;
+- struct node *np, *tmp;
+- off_t id;
+-
+ err = calculate_file_start (record, &file_start, rr);
+ if (err)
+ return err;
++
+ if (rr->valid & VALID_CL)
+ record = rr->realdirent;
+
+- /* First check the cache */
+ if (use_file_start_id (record, rr))
+- id = file_start << store->log2_block_size;
++ *idp = file_start << store->log2_block_size;
+ else
+- id = (off_t) ((void *) record - (void *) disk_image);
+-
+- pthread_rwlock_rdlock (&nodecache_lock);
+- inode_cache_find (id, npp);
+- pthread_rwlock_unlock (&nodecache_lock);
+- if (*npp)
+- return 0;
+-
+- /* Create a new node */
+- dn = malloc (sizeof (struct disknode));
+- if (!dn)
+- return ENOMEM;
+-
+- dn->fileinfo = 0;
+- dn->dr = record;
+- dn->file_start = file_start;
+-
+- np = diskfs_make_node (dn);
+- if (!np)
+- {
+- free (dn);
+- return ENOMEM;
+- }
+-
+- pthread_mutex_lock (&np->lock);
+-
+- pthread_rwlock_wrlock (&nodecache_lock);
+- tmp = lookup (id);
+- if (tmp)
+- {
+- /* We lost a race. */
+- diskfs_nput (np);
+- diskfs_nref (tmp);
+- *npp = tmp;
+- pthread_rwlock_unlock (&nodecache_lock);
+- return 0;
+- }
+-
+- cache_inode (np, record, rr);
+- pthread_rwlock_unlock (&nodecache_lock);
+-
+- err = read_disknode (np, record, rr);
+- *npp = np;
+- return err;
++ *idp = (off_t) ((void *) record - (void *) disk_image);
++ return 0;
+ }
+
+-
+ /* Read stat information from the directory entry at DR and the
+ contents of RL. */
+-static error_t
+-read_disknode (struct node *np, struct dirrect *dr,
+- struct rrip_lookup *rl)
++error_t
++diskfs_user_read_node (struct node *np, struct lookup_context *ctx)
+ {
+ error_t err;
+ struct stat *st = &np->dn_stat;
++ struct dirrect *dr = ctx->dr;
++ struct rrip_lookup *rl = &ctx->rr;
+ st->st_fstype = FSTYPE_ISO9660;
+ st->st_fsid = getpid ();
+- if (use_file_start_id (dr, rl))
+- st->st_ino = (ino_t) np->dn->file_start << store->log2_block_size;
+- else
+- st->st_ino = (ino_t) ((void *) dr - (void *) disk_image);
++ st->st_ino = np->cache_id;
+ st->st_gen = 0;
+ st->st_rdev = 0;
+
+@@ -547,39 +326,14 @@ diskfs_node_norefs (struct node *np)
+ free (np->dn->translator);
+
+ assert (!np->dn->fileinfo);
+- 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->cache_id != 0)
+- {
+- assert (node_cache[np->cache_id - 1].np == np);
+-
+- /* Check if someone reacquired a reference through the
+- node_cache. */
+- 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;
+- }
+-
+- 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);
+ }
+
+@@ -640,14 +394,6 @@ diskfs_validate_author_change (struct node *np, uid_t author)
+ return EROFS;
+ }
+
+-error_t
+-diskfs_node_iterate (error_t (*fun)(struct node *))
+-{
+- /* We never actually have to do anything, because this function
+- is only used for things that have to do with read-write media. */
+- return 0;
+-}
+-
+ void
+ diskfs_write_disknode (struct node *np, int wait)
+ {
+diff --git a/isofs/isofs.h b/isofs/isofs.h
+index 68a94e9..7362220 100644
+--- a/isofs/isofs.h
++++ b/isofs/isofs.h
+@@ -56,6 +56,12 @@ struct user_pager_info
+ struct pager *p;
+ };
+
++struct lookup_context
++{
++ struct dirrect *dr;
++ struct rrip_lookup rr;
++};
++
+ /* The physical media */
+ extern struct store *store;
+
+@@ -87,6 +93,9 @@ void drop_pager_softrefs (struct node *);
+ void allow_pager_softrefs (struct node *);
+ void create_disk_pager (void);
+
++/* Given RECORD and RR, calculate the cache id. */
++error_t cache_id (struct dirrect *record, struct rrip_lookup *rr, ino_t *idp);
++
+ error_t load_inode (struct node **, struct dirrect *, struct rrip_lookup *);
+ error_t calculate_file_start (struct dirrect *, off_t *, struct rrip_lookup *);
+
+diff --git a/isofs/lookup.c b/isofs/lookup.c
+index e51b9cb..f375212 100644
+--- a/isofs/lookup.c
++++ b/isofs/lookup.c
+@@ -70,12 +70,12 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
+ struct node **npp, struct dirstat *ds, struct protid *cred)
+ {
+ error_t err = 0;
+- struct dirrect *record;
++ struct lookup_context ctx;
+ int namelen;
+ int spec_dotdot;
+ void *buf;
+ void *blockaddr;
+- struct rrip_lookup rr;
++ ino_t id;
+
+ if ((type == REMOVE) || (type == RENAME))
+ assert (npp);
+@@ -99,7 +99,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
+ blockaddr < buf + dp->dn_stat.st_size;
+ blockaddr += logical_sector_size)
+ {
+- err = dirscanblock (blockaddr, name, namelen, &record, &rr);
++ err = dirscanblock (blockaddr, name, namelen, &ctx.dr, &ctx.rr);
+
+ if (!err)
+ break;
+@@ -115,6 +115,10 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
+ if (err)
+ return err;
+
++ err = cache_id (ctx.dr, &ctx.rr, &id);
++ if (err)
++ return err;
++
+ /* Load the inode */
+ if (namelen == 2 && name[0] == '.' && name[1] == '.')
+ {
+@@ -125,7 +129,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
+ /* renames and removes can't get this far. */
+ assert (type == LOOKUP);
+ diskfs_nput (dp);
+- err = load_inode (npp, record, &rr);
++ err = diskfs_cached_lookup_context (id, npp, &ctx);
+ }
+ else
+ {
+@@ -133,7 +137,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
+ we are permanently read-only, so things are necessarily
+ quiescent. Just be careful to honor the locking order. */
+ pthread_mutex_unlock (&dp->lock);
+- err = load_inode (npp, record, &rr);
++ err = diskfs_cached_lookup_context (id, npp, &ctx);
+ pthread_mutex_lock (&dp->lock);
+ }
+ }
+@@ -143,9 +147,9 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type,
+ diskfs_nref (dp);
+ }
+ else
+- err = load_inode (npp, record, &rr);
++ err = diskfs_cached_lookup_context (id, npp, &ctx);
+
+- release_rrip (&rr);
++ release_rrip (&ctx.rr);
+ return err;
+ }
+
+diff --git a/isofs/main.c b/isofs/main.c
+index 4f531f7..95c90fe 100644
+--- a/isofs/main.c
++++ b/isofs/main.c
+@@ -44,20 +44,23 @@ int diskfs_maxsymlinks = 8;
+ static void
+ fetch_root ()
+ {
+- struct rrip_lookup rl;
+- struct dirrect *dr;
++ struct lookup_context ctx;
++ ino_t id;
+ error_t err;
+
+- dr = (struct dirrect *) sblock->root;
++ ctx.dr = (struct dirrect *) sblock->root;
+
+ /* First check for SUSP and all relevant extensions */
+- rrip_initialize (dr);
++ rrip_initialize (ctx.dr);
+
+ /* Now rescan the node for real */
+- rrip_lookup (dr, &rl, 1);
++ rrip_lookup (ctx.dr, &ctx.rr, 1);
++
++ err = cache_id (ctx.dr, &ctx.rr, &id);
++ assert_perror (err);
+
+ /* And fetch the node. */
+- err = load_inode (&diskfs_root_node, dr, &rl);
++ err = diskfs_cached_lookup_context (id, &diskfs_root_node, &ctx);
+ assert_perror (err);
+
+ pthread_mutex_unlock (&diskfs_root_node->lock);
+diff --git a/isofs/rr.c b/isofs/rr.c
+index adc95c3..2429fae 100644
+--- a/isofs/rr.c
++++ b/isofs/rr.c
+@@ -38,10 +38,13 @@ release_rrip (struct rrip_lookup *rr)
+ {
+ if ((rr->valid & VALID_NM) && rr->name)
+ free (rr->name);
++ rr->name = NULL;
+ if ((rr->valid & VALID_SL) && rr->target)
+ free (rr->target);
++ rr->target = NULL;
+ if ((rr->valid & VALID_TR) && rr->trans)
+ free (rr->trans);
++ rr->trans = NULL;
+ }
+
+
+@@ -51,6 +54,7 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr,
+ const char *match_name, size_t match_name_len,
+ int initializing, int ignorenm)
+ {
++ // error (0, 0, "rrip_work %p %p %s %d %d %d", dr, rr, match_name, match_name_len, initializing, ignorenm);
+ void *bp, *terminus;
+ void *slbuf, *nmbuf;
+ size_t slbufsize, nmbufsize;
+--
+2.1.4
+