From e3b1ae2acca631296b3fdc3342a543beac69360a Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 26 Nov 2000 16:53:40 +0000 Subject: 2000-11-26 Marcus Brinkmann Fix hard link handling for non-zero length files. * inode.c: Fix comment about inode numbers. (node_cache): New member ID to store unique identifier. (inode_cache_find): Change RECORD arg into ID and compare it with id member of node_cache. (cache_inode): Swap order of args and add new arg RR (change dr into record along the way). Use RR to find out cache ID. Use id member of node_cache to look for ID. Cache ID. (load_inode): Call inode_cache_find with correct ID, depending on RR and file size. Frob arguments to cache_inode to comply with the new definition. (read_disknode): Set st_ino according depending on RR and file size. * lookup.c: Doc spelling fix. (diskfs_get_directs): Include code again that was removed by last change, but use it only if not symlink or zero length file. --- isofs/ChangeLog | 18 ++++++++++++++++++ isofs/inode.c | 56 ++++++++++++++++++++++++++++++++++++-------------------- isofs/lookup.c | 21 +++++++++++++++++++-- 3 files changed, 73 insertions(+), 22 deletions(-) (limited to 'isofs') diff --git a/isofs/ChangeLog b/isofs/ChangeLog index 69f5def6..defe71e2 100644 --- a/isofs/ChangeLog +++ b/isofs/ChangeLog @@ -1,3 +1,21 @@ +2000-11-26 Marcus Brinkmann + + Fix hard link handling for non-zero length files. + * inode.c: Fix comment about inode numbers. + (node_cache): New member ID to store unique identifier. + (inode_cache_find): Change RECORD arg into ID and compare it + with id member of node_cache. + (cache_inode): Swap order of args and add new arg RR (change dr + into record along the way). Use RR to find out cache ID. + Use id member of node_cache to look for ID. Cache ID. + (load_inode): Call inode_cache_find with correct ID, depending + on RR and file size. Frob arguments to cache_inode to comply with + the new definition. + (read_disknode): Set st_ino according depending on RR and file size. + * lookup.c: Doc spelling fix. + (diskfs_get_directs): Include code again that was removed by last change, + but use it only if not symlink or zero length file. + 2000-11-26 Marcus Brinkmann Closes Debian Bug #68417: diff --git a/isofs/inode.c b/isofs/inode.c index 149031fa..ddb4b615 100644 --- a/isofs/inode.c +++ b/isofs/inode.c @@ -25,9 +25,9 @@ /* There is no such thing as an inode in this format, all such information being recorded in the directory entry. So we report - inode numbers as absolute offsets from DISK_IMAGE. But we can't use - the file start because of symlinks (and zero length files?), so we - use the directory record itself. */ + inode numbers as absolute offsets from DISK_IMAGE. We use the directory + 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) @@ -39,9 +39,10 @@ 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 */ }; @@ -54,17 +55,17 @@ static error_t read_disknode (struct node *, struct dirrect *, struct rrip_lookup *); -/* See if node with directory entry RECORD is in the cache. If so, - return it, with one additional reference. diskfs_node_refcnt_lock - must be held on entry to the call, and will be released iff the - node was found in the cache. */ +/* 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 + on entry to the call, and will be released iff the node was found + in the cache. */ void -inode_cache_find (struct dirrect *record, struct node **npp) +inode_cache_find (off_t id, struct node **npp) { int i; for (i = 0; i < node_cache_size; i++) - if (node_cache[i].dr == record + if (node_cache[i].id == id && node_cache[i].np) { *npp = node_cache[i].np; @@ -76,17 +77,24 @@ inode_cache_find (struct dirrect *record, struct node **npp) *npp = 0; } -/* Enter NP into the cache. The directory entry we used - DR. diskfs_node_refcnt_lock must be held. */ +/* 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. */ void -cache_inode (struct dirrect *dr, struct node *np) +cache_inode (struct node *np, struct dirrect *record, + struct rrip_lookup *rr) { int i; struct node_cache *c = 0; + off_t id; + + if (rr->valid & VALID_SL || isonum_733 (record->size) == 0) + id = (off_t) ((void *) record - (void *) disk_image); + else + id = np->dn->file_start; /* First see if there's already an entry. */ for (i = 0; i < node_cache_size; i++) - if (node_cache[i].dr == np->dn->dr) + if (node_cache[i].id == id) break; if (i == node_cache_size) @@ -112,7 +120,8 @@ cache_inode (struct dirrect *dr, struct node *np) } c = &node_cache[i]; - c->dr = dr; + c->id = id; + c->dr = record; c->file_start = np->dn->file_start; c->np = np; @@ -262,8 +271,8 @@ calculate_file_start (struct dirrect *record, off_t *file_start, } -/* Load the inode with directory entry RECORD and cached Rock-Rodge info RR - into NP. The directory entry is at OFFSET in BLOCK. */ +/* Load the inode with directory entry RECORD and cached Rock-Ridge + info RR into NP. The directory entry is at OFFSET in BLOCK. */ error_t load_inode (struct node **npp, struct dirrect *record, struct rrip_lookup *rr) @@ -282,7 +291,11 @@ load_inode (struct node **npp, struct dirrect *record, spin_lock (&diskfs_node_refcnt_lock); /* First check the cache */ - inode_cache_find (record, npp); + if (rr->valid & VALID_SL || isonum_733 (record->size) == 0) + inode_cache_find ((off_t) ((void *) record - (void *) disk_image), npp); + else + inode_cache_find (file_start, npp); + if (*npp) return 0; @@ -296,7 +309,7 @@ load_inode (struct node **npp, struct dirrect *record, mutex_lock (&np->lock); - cache_inode (record, np); + cache_inode (np, record, rr); spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np, record, rr); @@ -315,7 +328,10 @@ read_disknode (struct node *np, struct dirrect *dr, struct stat *st = &np->dn_stat; st->st_fstype = FSTYPE_ISO9660; st->st_fsid = getpid (); - st->st_ino = (ino_t) ((void *) np->dn->dr - (void *) disk_image); + if (rl->valid & VALID_SL || isonum_733 (dr->size) == 0) + st->st_ino = (ino_t) ((void *) dr - (void *) disk_image); + else + st->st_ino = (ino_t) np->dn->file_start; st->st_gen = 0; st->st_rdev = 0; diff --git a/isofs/lookup.c b/isofs/lookup.c index e6d2caf4..d8325a9d 100644 --- a/isofs/lookup.c +++ b/isofs/lookup.c @@ -179,7 +179,7 @@ dirscanblock (void *blkaddr, const char *name, size_t namelen, if (reclen < sizeof (struct dirrect) + entry_namelen) break; - /* Check to see if the name maches the directory entry. */ + /* Check to see if the name matches the directory entry. */ if (isonamematch (entry->name, entry_namelen, name, namelen)) matchnormal = 1; else @@ -353,7 +353,24 @@ diskfs_get_directs (struct node *dp, /* Fill in entry */ - userp->d_fileno = (ino_t) ((void *) ep - (void *) disk_image); + if (rr.valid & VALID_SL || isonum_733 (ep->size) == 0) + userp->d_fileno = (ino_t) ((void *) ep - (void *) disk_image); + else + { + off_t file_start; + + err = calculate_file_start (ep, &file_start, &rr); + if (err) + { + diskfs_end_catch_exception (); + if (ouralloc) + munmap (*data, allocsize); + return err; + } + + userp->d_fileno = file_start; + } + userp->d_type = DT_UNKNOWN; userp->d_reclen = reclen; userp->d_namlen = namlen; -- cgit v1.2.3