diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-04-17 14:17:23 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-04-17 14:17:23 +0200 |
commit | 7f240848cb840544124d08b1a317309d6dc9107e (patch) | |
tree | 1c7eddb9fd1aba2f8822d6f1f1e8b2b07e858ca5 /debian/patches/0012-isofs-port-to-libdiskfs-node-cache.patch | |
parent | cc37b9eaebce8c8f2b7c00607c7cac5e7eda6a27 (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.patch | 573 |
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 + |