summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Brinkmann <marcus@gnu.org>2000-11-26 16:53:40 +0000
committerMarcus Brinkmann <marcus@gnu.org>2000-11-26 16:53:40 +0000
commite3b1ae2acca631296b3fdc3342a543beac69360a (patch)
tree8972fa01b27d5593d5ca89ed83b0e3a803f9fa70
parentce0f972cecd30fc1457aa0a9a0fa1ad966d23c12 (diff)
2000-11-26 Marcus Brinkmann <marcus@gnu.org>
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.
-rw-r--r--isofs/ChangeLog18
-rw-r--r--isofs/inode.c56
-rw-r--r--isofs/lookup.c21
3 files changed, 73 insertions, 22 deletions
diff --git a/isofs/ChangeLog b/isofs/ChangeLog
index 69f5def6..defe71e2 100644
--- a/isofs/ChangeLog
+++ b/isofs/ChangeLog
@@ -1,5 +1,23 @@
2000-11-26 Marcus Brinkmann <marcus@gnu.org>
+ 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 <marcus@gnu.org>
+
Closes Debian Bug #68417:
* rr.c (rrip_work): In helper function add_comp set targused to
zero after malloc, and loop over realloc in case doubling is not
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;