--- vanilla-2.4.1/fs/isofs/inode.c Tue Feb 6 02:17:08 2001 +++ cisofs/fs/isofs/inode.c Mon Feb 19 19:45:15 2001 @@ -7,6 +7,7 @@ * 1995 Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs. * 1997 Gordon Chaffee - Joliet CDs * 1998 Eric Lammerts - ISO 9660 Level 3 + * 2001 zhaoway - Transparent *.cramed uncompressing */ #include @@ -55,6 +56,12 @@ static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); #endif +#ifdef CONFIG_CISOFS +int cisofs_uncompress_block(void *dst, int dstlen, void *src, int srclen); +int cisofs_uncompress_init(void); +int cisofs_uncompress_exit(void); +#endif + static void isofs_put_super(struct super_block *sb) { #ifdef CONFIG_JOLIET @@ -981,7 +988,97 @@ static int isofs_readpage(struct file *file, struct page *page) { - return block_read_full_page(page,isofs_get_block); +#ifdef CONFIG_CISOFS + struct inode *inode = page->mapping->host; + + if (! inode->u.isofs_i.i_compr) +#endif + return block_read_full_page(page,isofs_get_block); +#ifdef CONFIG_CISOFS + else { + u32 bytes_filled, pageptr_offset, pageptr_blk_offset; + u32 start_offset, end_offset, iblk_offset, compr_len; + unsigned long iblk, end_blk; + struct buffer_head *bh = NULL; + char compr[PAGE_CACHE_SIZE * 2]; + + unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); + unsigned char bufbits = ISOFS_BUFFER_BITS(inode); + + bytes_filled = 0; + if (page->index > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT)) { + printk("cisofs: page->index > maxpage\n"); + goto out; + } + +#if 1 + printk("cisofs: yow! before pageptr bread!\n"); +#endif + pageptr_offset = page->index * 8; + pageptr_blk_offset = pageptr_offset & (bufsize - 1); + iblk = pageptr_offset >> bufbits; + if (! (bh = isofs_bread(inode, bufsize, iblk))) { + printk("cisofs: bad pageptr bread: %ld\n", iblk); + goto out; + } +#if 1 + printk("cisofs: yow! after pageptr bread!\n"); +#endif + start_offset = (u32) bh->b_data[pageptr_blk_offset]; + end_offset = (u32) bh->b_data[pageptr_blk_offset + 4]; + brelse(bh); + bh = NULL; + + end_blk = end_offset >> bufbits; + iblk = start_offset >> bufbits; + iblk_offset = start_offset & (bufsize - 1); + + compr_len = end_offset - start_offset; + if (compr_len == 0) + ; /* hole */ + else { + char *curr = compr; + + while (iblk <= end_blk) { + u32 size; + + if (! (bh = isofs_bread(inode, bufsize, iblk))) { + printk("cisofs: bad bread: %ld\n", iblk); + goto out; + } +#if 1 + printk("cisofs: yow! good bread!\n"); +#endif + if (iblk++ < end_blk) + size = bufsize - iblk_offset; + else + size = (end_offset & (bufsize - 1)) - iblk_offset; + memcpy(curr, bh->b_data + iblk_offset, size); + brelse(bh); + bh = NULL; + curr += size; + iblk_offset = 0; + } + + if ((curr - compr) != compr_len) { + printk("cisofs: curr - compr != compr_len\n"); + goto out; + } + bytes_filled = cisofs_uncompress_block(page_address(page), + PAGE_CACHE_SIZE, + compr, compr_len); + } + + out: + memset(page_address(page) + bytes_filled, 0, + PAGE_CACHE_SIZE - bytes_filled); + flush_dcache_page(page); + SetPageUptodate(page); + UnlockPage(page); + return 0; + } +#endif /* CONFIG_CISOFS */ } static int _isofs_bmap(struct address_space *mapping, long block) @@ -1328,11 +1425,17 @@ static int __init init_iso9660_fs(void) { +#ifdef CONFIG_CISOFS + cisofs_uncompress_init(); +#endif return register_filesystem(&iso9660_fs_type); } static void __exit exit_iso9660_fs(void) { +#ifdef CONFIG_CISOFS + cisofs_uncompress_exit(); +#endif unregister_filesystem(&iso9660_fs_type); }