Messages in this thread Patch in this message | | | Date | Sun, 29 Jun 1997 23:29:02 -0400 (EDT) | From | "Jonathan F. Freeson" <> | Subject | Linux ISO9660 File System |
| |
Hello:
I noticed that with some of the later 2.1.x kernels, I have been unable to read some of my older "Shareware" CD-ROMs that I was able to read with 2.0.30. With 2.1, I frequently got the kernel message:
Directory entry extends past end of iso9660 block
Browsing through fs/isofs/namei.c, I found where this message occur (line 116).
/* Handle case where the directory entry spans two blocks. Usually 1024 byte boundaries */ if (offset >= bufsize) { printk("Directory entry extends past end of iso9660 block\n"); return 0; }
However, in 2.0.30, a different piece of code is executed inside the if statement.
After replacing the 2.1.43 code with the 2.0.30 portion (as well as all references to the "cpnt" buffer), the CD's seem to work with 2.1.43 now.
Was there some particular reason why the support was removed for these sort of directory entries? Will my fix (kludge) break anything else? I am not familar with this filesystem, so I can't dive into the code and figure it out.
I'm attaching a copy of the diff to what I have changed. It is against the fs/isofs/namei.c in 2.1.43.
Sorry if this is a subject that has already been discussed.
Thanks
--- Jonathan F. Freeson jfreeson@gopher.science.wayne.edu jff1@ss0.eng.wayne.edu Homepage: http://www.science.wayne.edu/~jfreeson/index.html
--- namei.c.old Sun Jun 29 00:14:58 1997 +++ namei.c Sun Jun 29 00:20:33 1997 @@ -65,6 +65,7 @@ unsigned char bufbits = ISOFS_BUFFER_BITS(dir); unsigned int block, i, f_pos, offset, inode_number; struct buffer_head * bh; + void * cpnt = NULL; unsigned int old_offset; unsigned int backlink; int dlen, rrflag, match; @@ -116,8 +117,21 @@ /* Handle case where the directory entry spans two blocks. Usually 1024 byte boundaries */ if (offset >= bufsize) { - printk("Directory entry extends past end of iso9660 block\n"); - return 0; + unsigned int frag1; + frag1 = bufsize - old_offset; + cpnt = kmalloc(*((unsigned char *) de),GFP_KERNEL); + if (!cpnt) return 0; + 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 = bread(dir->i_dev,block,bufsize))) { + kfree(cpnt); + return 0; + }; + memcpy((char *)cpnt+frag1, bh->b_data, offset); } /* Handle the '.' case */ @@ -176,6 +190,12 @@ match = isofs_match(namelen,name,dpnt,dlen); } + if (cpnt) + { + kfree(cpnt); + cpnt = NULL; + } + if(rrflag) kfree(dpnt); if (match) { if(inode_number == -1) { @@ -197,6 +217,8 @@ } } out: + if (cpnt) + kfree(cpnt); brelse(bh); return NULL; } | |