diff options
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.patch | 573 |
1 files changed, 0 insertions, 573 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 deleted file mode 100644 index d32cc611..00000000 --- a/debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch +++ /dev/null @@ -1,573 +0,0 @@ -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 - |