summaryrefslogtreecommitdiff
path: root/isofs
diff options
context:
space:
mode:
authorMarcus Brinkmann <marcus@gnu.org>2000-11-27 19:58:35 +0000
committerMarcus Brinkmann <marcus@gnu.org>2000-11-27 19:58:35 +0000
commitdcf87038f6e0cba736b974204a7e8c1bbe2c4858 (patch)
tree96dc178cd1706247113e505c45d50a9571bfcb3e /isofs
parentea5ea50352cde95ee275859aba3b5d0bb0c3d341 (diff)
2000-11-27 Marcus Brinkmann <marcus@gnu.org>
The last two changes introduced two new inode overlaps (file_start was not shifted by store block size, and directories' shifted file_start offset can be the same as the struct dirrect offset of their first directory entry). * inode.c (use_file_start_as_id): New function to determine if to use file_start or struct dirrect * as node id. The directory recognition code comes from read_disknode. (cache_inode): Use use_file_start_as_id instead doing the work ourselve. Shift file_start by store->log2_block_size. (load_inode): Likewise. * lookup.c (diskfs_get_directs): Likewise. Declare use_file_start_id.
Diffstat (limited to 'isofs')
-rw-r--r--isofs/ChangeLog16
-rw-r--r--isofs/inode.c48
-rw-r--r--isofs/lookup.c13
3 files changed, 63 insertions, 14 deletions
diff --git a/isofs/ChangeLog b/isofs/ChangeLog
index defe71e2..c87053fc 100644
--- a/isofs/ChangeLog
+++ b/isofs/ChangeLog
@@ -1,3 +1,19 @@
+2000-11-27 Marcus Brinkmann <marcus@gnu.org>
+
+ The last two changes introduced two new inode overlaps
+ (file_start was not shifted by store block size, and directories'
+ shifted file_start offset can be the same as the struct dirrect
+ offset of their first directory entry).
+
+ * inode.c (use_file_start_as_id): New function to determine
+ if to use file_start or struct dirrect * as node id.
+ The directory recognition code comes from read_disknode.
+ (cache_inode): Use use_file_start_as_id instead doing the work
+ ourselve. Shift file_start by store->log2_block_size.
+ (load_inode): Likewise.
+ * lookup.c (diskfs_get_directs): Likewise.
+ Declare use_file_start_id.
+
2000-11-26 Marcus Brinkmann <marcus@gnu.org>
Fix hard link handling for non-zero length files.
diff --git a/isofs/inode.c b/isofs/inode.c
index ddb4b615..2aa73a93 100644
--- a/isofs/inode.c
+++ b/isofs/inode.c
@@ -77,6 +77,36 @@ inode_cache_find (off_t id, struct node **npp)
*npp = 0;
}
+
+/* Determine if we use file_start or struct dirrect * as node id. */
+int
+use_file_start_id (struct dirrect *record, struct rrip_lookup *rr)
+{
+ /* If it is a directory, don't use file_start. */
+ if (rr->valid & VALID_PX)
+ {
+ if (((rr->valid & VALID_MD) == 0) && (rr->mode & S_IFDIR))
+ return 0;
+ }
+ else
+ if ((rr->valid & VALID_MD) == 0)
+ {
+ /* If there are no periods, it's a directory. */
+ if (((rr->valid & VALID_NM) && !index (rr->name, '.'))
+ || (!(rr->valid & VALID_NM) && !memchr (record->name, '.',
+ record->namelen)))
+ return 0;
+ }
+ if ((rr->valid & VALID_MD) && (rr->allmode & S_IFDIR))
+ return 0;
+
+ /* If it is a symlink or a zero length file, don't use file_start. */
+ if (rr->valid & VALID_SL || isonum_733 (record->size) == 0)
+ return 0;
+
+ return 1;
+}
+
/* 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
@@ -87,10 +117,10 @@ cache_inode (struct node *np, struct dirrect *record,
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);
+ if (use_file_start_id (record, rr))
+ id = np->dn->file_start << store->log2_block_size;
else
- id = np->dn->file_start;
+ id = (off_t) ((void *) record - (void *) disk_image);
/* First see if there's already an entry. */
for (i = 0; i < node_cache_size; i++)
@@ -291,10 +321,10 @@ load_inode (struct node **npp, struct dirrect *record,
spin_lock (&diskfs_node_refcnt_lock);
/* First check the cache */
- if (rr->valid & VALID_SL || isonum_733 (record->size) == 0)
- inode_cache_find ((off_t) ((void *) record - (void *) disk_image), npp);
+ if (use_file_start_id (record, rr))
+ inode_cache_find (file_start << store->log2_block_size, npp);
else
- inode_cache_find (file_start, npp);
+ inode_cache_find ((off_t) ((void *) record - (void *) disk_image), npp);
if (*npp)
return 0;
@@ -328,10 +358,10 @@ read_disknode (struct node *np, struct dirrect *dr,
struct stat *st = &np->dn_stat;
st->st_fstype = FSTYPE_ISO9660;
st->st_fsid = getpid ();
- if (rl->valid & VALID_SL || isonum_733 (dr->size) == 0)
- st->st_ino = (ino_t) ((void *) dr - (void *) disk_image);
+ 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) np->dn->file_start;
+ st->st_ino = (ino_t) ((void *) dr - (void *) disk_image);
st->st_gen = 0;
st->st_rdev = 0;
diff --git a/isofs/lookup.c b/isofs/lookup.c
index d8325a9d..e6ee692f 100644
--- a/isofs/lookup.c
+++ b/isofs/lookup.c
@@ -22,6 +22,9 @@
#include <dirent.h>
#include "isofs.h"
+/* From inode.c */
+int use_file_start_id (struct dirrect *record, struct rrip_lookup *rr);
+
/* Forward */
static error_t dirscanblock (void *, const char *, size_t,
struct dirrect **, struct rrip_lookup *);
@@ -353,12 +356,10 @@ diskfs_get_directs (struct node *dp,
/* Fill in entry */
- if (rr.valid & VALID_SL || isonum_733 (ep->size) == 0)
- userp->d_fileno = (ino_t) ((void *) ep - (void *) disk_image);
- else
+ if (use_file_start_id (ep, &rr))
{
off_t file_start;
-
+
err = calculate_file_start (ep, &file_start, &rr);
if (err)
{
@@ -368,8 +369,10 @@ diskfs_get_directs (struct node *dp,
return err;
}
- userp->d_fileno = file_start;
+ userp->d_fileno = file_start << store->log2_block_size;
}
+ else
+ userp->d_fileno = (ino_t) ((void *) ep - (void *) disk_image);
userp->d_type = DT_UNKNOWN;
userp->d_reclen = reclen;