lkml.org 
[lkml]   [1999]   [Apr]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: small fixes to isofs

Mircea Damian <mbircea@pop3.kappa.ro> writes:
> I've found a problem in the isofs. I do have a data CD which seems to
> mount well but I only see there 2 files. The same CD works just fine
> in Windoze 95/98 and shows all files.

Don't know, but this could be related to another problem report I got.
For some reason, someone removed code that existed in 2.0.x that dealt
with illegally formatted CDs. While illegally formatted, there are
plenty of old CDs that have this problem. Also, these CDs are read
without problems by Macs and Win95/NT. The following patch restores
the behavior from 2.0.x. It has not been tested enough, but you could
try and see if it fixes your problem.

- Gordon

--- linux-2.2.3-clean/fs/isofs/namei.c Fri Jan 15 14:41:04 1999
+++ linux/fs/isofs/namei.c Tue Apr 20 08:53:56 1999
@@ -65,12 +65,12 @@
unsigned int block, i, f_pos, offset,
inode_number = 0; /* shut gcc up */
struct buffer_head * bh , * retval = NULL;
+ void * cpnt = NULL;
unsigned int old_offset;
int dlen, match;
char * dpnt;
unsigned char *page = NULL;
struct iso_directory_record * de = NULL; /* shut gcc up */
- char de_not_in_buf = 0; /* true if de is in kmalloc'd memory */
char c;

*ino = 0;
@@ -86,13 +86,8 @@
if (!block || !(bh = bread(dir->i_dev,block,bufsize))) return NULL;

while (f_pos < dir->i_size) {
+ de = (struct iso_directory_record *) (bh->b_data + offset);

- /* if de is in kmalloc'd memory, do not point to the
- next de, instead we will move to the next sector */
- if(!de_not_in_buf) {
- de = (struct iso_directory_record *)
- (bh->b_data + offset);
- }
inode_number = (block << bufbits) + (offset & (bufsize - 1));

/* If byte is zero, or we had to fetch this de past
@@ -100,25 +95,13 @@
time to move to the next sector. Usually 2048 byte
boundaries. */

- if (*((unsigned char *) de) == 0 || de_not_in_buf) {
- if(de_not_in_buf) {
- /* james@bpgc.com: Since we slopped
- past the end of the last buffer, we
- must start some way into the new
- one */
- de_not_in_buf = 0;
- kfree(de);
- f_pos += offset;
- }
- else {
- offset = 0;
- f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1))
- + ISOFS_BLOCK_SIZE);
- }
+ if (de->length[0] == 0) {
brelse(bh);
bh = NULL;
-
- if (f_pos >= dir->i_size)
+ offset = 0;
+ f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1))
+ + ISOFS_BLOCK_SIZE);
+ if (f_pos >= dir->i_size)
break;

block = isofs_bmap(dir,f_pos>>bufbits);
@@ -129,33 +112,31 @@
}

old_offset = offset;
- offset += *((unsigned char *) de);
- f_pos += *((unsigned char *) de);
+ offset += de->length[0];
+ f_pos += de->length[0];

- /* james@bpgc.com: new code to handle case where the
- directory entry spans two blocks. Usually 1024
- byte boundaries */
- if (offset >= bufsize) {
- struct buffer_head *bh_next;
-
- /* james@bpgc.com: read the next block, and
- copy the split de into a newly kmalloc'd
- buffer */
+ /* Handle case where the directory entry spans two blocks.
+ Usually 1024 byte boundaries */
+ if (offset > bufsize) {
+ unsigned int frag1;
+ frag1 = bufsize - old_offset;
+ if (! page) {
+ page = (unsigned char *)
+ __get_free_page(GFP_KERNEL);
+ if (!page) break;
+ }
+ cpnt = page + 1024;
+ memcpy(cpnt, bh->b_data + old_offset, frag1);
+
+ de = (struct iso_directory_record *) cpnt;
+ brelse(bh);
+ offset = f_pos & (bufsize - 1);
block = isofs_bmap(dir,f_pos>>bufbits);
- if (!block ||
- !(bh_next = bread(dir->i_dev,block,bufsize)))
+ if (!block || !(bh = bread(dir->i_dev,block,bufsize)))
break;
-
- de = (struct iso_directory_record *)
- kmalloc(offset - old_offset, GFP_KERNEL);
- memcpy((char *)de, bh->b_data + old_offset,
- bufsize - old_offset);
- memcpy((char *)de + bufsize - old_offset,
- bh_next->b_data, offset - bufsize);
- brelse(bh_next);
- de_not_in_buf = 1;
- offset -= bufsize;
+ memcpy((char *)cpnt+frag1, bh->b_data, offset);
}
+
dlen = de->name_len[0];
dpnt = de->name;

@@ -223,8 +204,6 @@
}
if (page) free_page((unsigned long) page);
if (bh) brelse(bh);
- if(de_not_in_buf)
- kfree(de);
return retval;
}

--- linux-2.2.3-clean/fs/isofs/dir.c Thu Nov 12 11:44:09 1998
+++ linux/fs/isofs/dir.c Tue Apr 20 07:02:38 1999
@@ -151,7 +151,7 @@
return 0;

while (filp->f_pos < inode->i_size) {
- int de_len;
+ int de_len, next_offset;
#ifdef DEBUG
printk("Block, offset, f_pos: %x %x %x\n",
block, offset, filp->f_pos);
@@ -160,7 +160,7 @@
de = (struct iso_directory_record *) (bh->b_data + offset);
if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));

- de_len = *(unsigned char *) de;
+ de_len = de->length[0];
#ifdef DEBUG
printk("de_len = %ld\n", de_len);
#endif
@@ -190,21 +190,40 @@
bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size);
if (!bh)
return 0;
+ de = (struct iso_directory_record *) (bh->b_data + offset);
continue;
}

- offset += de_len;
- if (offset > bufsize) {
+ next_offset = offset + de_len;
+ if (offset + de_len > bufsize) {
/*
* This would only normally happen if we had
* a buggy cdrom image. All directory
* entries should terminate with a null size
* or end exactly at the end of the sector.
- */
+ * However, some older CDs did not follow the
+ * standard quite as well as they should, so we
+ * need to support the case of the directory entry
+ * crossing over the end of a logical sector.
+ */
+#ifdef DEBUG
printk("next_offset (%x) > bufsize (%lx)\n",
- offset,bufsize);
- break;
+ next_offset,bufsize);
+#endif
+ next_offset &= (bufsize - 1);
+ memcpy(tmpde, de, bufsize - offset);
+ brelse(bh);
+
+ block = isofs_bmap(inode, (filp->f_pos + de_len) >> bufbits);
+ if (!block)
+ return 0;
+ bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size);
+ if (!bh)
+ return 0;
+ memcpy(bufsize - offset + (char *) tmpde, bh->b_data, next_offset);
+ de = tmpde;
}
+ offset = next_offset;

if(de->flags[-high_sierra] & 0x80) {
first_de = 0;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:51    [W:0.095 / U:0.152 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site