From: Andy P. <at...@us...> - 2002-04-09 15:13:39
|
Update of /cvsroot/linux-vax/kernel-2.4/fs/cramfs In directory usw-pr-cvs1:/tmp/cvs-serv25633/cramfs Modified Files: Makefile README inode.c uncompress.c Removed Files: cramfs.h Log Message: synch 2.4.15 commit 9 Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/cramfs/Makefile,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- Makefile 14 Jan 2001 16:40:09 -0000 1.1.1.1 +++ Makefile 9 Apr 2002 13:01:37 -0000 1.2 @@ -4,11 +4,10 @@ O_TARGET := cramfs.o -obj-y := inode.o uncompress.o inflate/zlib.o +obj-y := inode.o uncompress.o obj-m := $(O_TARGET) -include $(TOPDIR)/Rules.make +CFLAGS_uncompress.o := -I $(TOPDIR)/fs/inflate_fs -inflate/zlib.o: - make -C inflate +include $(TOPDIR)/Rules.make Index: README =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/cramfs/README,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- README 14 Jan 2001 16:40:11 -0000 1.1.1.1 +++ README 9 Apr 2002 13:01:37 -0000 1.2 @@ -14,11 +14,11 @@ <directory_structure> <data> -<superblock>: struct cramfs_super (see cramfs.h). +<superblock>: struct cramfs_super (see cramfs_fs.h). <directory_structure>: For each file: - struct cramfs_inode (see cramfs.h). + struct cramfs_inode (see cramfs_fs.h). Filename. Not generally null-terminated, but it is null-padded to a multiple of 4 bytes. Index: inode.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/cramfs/inode.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- inode.c 14 Jan 2001 16:40:10 -0000 1.1.1.1 +++ inode.c 9 Apr 2002 13:01:37 -0000 1.2 @@ -17,10 +17,16 @@ #include <linux/init.h> #include <linux/string.h> #include <linux/locks.h> +#include <linux/blkdev.h> +#include <linux/cramfs_fs.h> #include <asm/uaccess.h> -#include "cramfs.h" +#define CRAMFS_SB_MAGIC u.cramfs_sb.magic +#define CRAMFS_SB_SIZE u.cramfs_sb.size +#define CRAMFS_SB_BLOCKS u.cramfs_sb.blocks +#define CRAMFS_SB_FILES u.cramfs_sb.files +#define CRAMFS_SB_FLAGS u.cramfs_sb.flags static struct super_operations cramfs_ops; static struct inode_operations cramfs_dir_inode_operations; @@ -40,6 +46,8 @@ inode->i_mode = cramfs_inode->mode; inode->i_uid = cramfs_inode->uid; inode->i_size = cramfs_inode->size; + inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; + inode->i_blksize = PAGE_CACHE_SIZE; inode->i_gid = cramfs_inode->gid; inode->i_ino = CRAMINO(cramfs_inode); /* inode->i_nlink is left 1 - arguably wrong for directories, @@ -100,7 +108,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) { struct buffer_head * bh_array[BLKS_PER_BUF]; - unsigned i, blocknr, buffer; + struct buffer_head * read_array[BLKS_PER_BUF]; + unsigned i, blocknr, buffer, unread; + unsigned long devsize; + int major, minor; + char *data; if (!len) @@ -123,9 +135,34 @@ return read_buffers[i] + blk_offset; } + devsize = ~0UL; + major = MAJOR(sb->s_dev); + minor = MINOR(sb->s_dev); + + if (blk_size[major]) + devsize = blk_size[major][minor] >> 2; + /* Ok, read in BLKS_PER_BUF pages completely first. */ - for (i = 0; i < BLKS_PER_BUF; i++) - bh_array[i] = bread(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE); + unread = 0; + for (i = 0; i < BLKS_PER_BUF; i++) { + struct buffer_head *bh; + + bh = NULL; + if (blocknr + i < devsize) { + bh = getblk(sb->s_dev, blocknr + i, PAGE_CACHE_SIZE); + if (!buffer_uptodate(bh)) + read_array[unread++] = bh; + } + bh_array[i] = bh; + } + + if (unread) { + ll_rw_block(READ, unread, read_array); + do { + unread--; + wait_on_buffer(read_array[unread]); + } while (unread); + } /* Ok, copy them to the staging area without sleeping. */ buffer = next_buffer; @@ -138,7 +175,7 @@ struct buffer_head * bh = bh_array[i]; if (bh) { memcpy(data, bh->b_data, PAGE_CACHE_SIZE); - bforget(bh); + brelse(bh); } else memset(data, 0, PAGE_CACHE_SIZE); data += PAGE_CACHE_SIZE; @@ -167,36 +204,51 @@ /* Do sanity checks on the superblock */ if (super.magic != CRAMFS_MAGIC) { - printk("wrong magic\n"); - goto out; - } - if (memcmp(super.signature, CRAMFS_SIGNATURE, sizeof(super.signature))) { - printk("wrong signature\n"); - goto out; + /* check at 512 byte offset */ + memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super)); + if (super.magic != CRAMFS_MAGIC) { + printk(KERN_ERR "cramfs: wrong magic\n"); + goto out; + } } + + /* get feature flags first */ if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { - printk("unsupported filesystem features\n"); + printk(KERN_ERR "cramfs: unsupported filesystem features\n"); goto out; } /* Check that the root inode is in a sane state */ if (!S_ISDIR(super.root.mode)) { - printk("root is not a directory\n"); + printk(KERN_ERR "cramfs: root is not a directory\n"); goto out; } root_offset = super.root.offset << 2; + if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { + sb->CRAMFS_SB_SIZE=super.size; + sb->CRAMFS_SB_BLOCKS=super.fsid.blocks; + sb->CRAMFS_SB_FILES=super.fsid.files; + } else { + sb->CRAMFS_SB_SIZE=1<<28; + sb->CRAMFS_SB_BLOCKS=0; + sb->CRAMFS_SB_FILES=0; + } + sb->CRAMFS_SB_MAGIC=super.magic; + sb->CRAMFS_SB_FLAGS=super.flags; if (root_offset == 0) - printk(KERN_INFO "cramfs: note: empty filesystem"); - else if (root_offset != sizeof(struct cramfs_super)) { - printk("bad root offset %lu\n", root_offset); + printk(KERN_INFO "cramfs: empty filesystem"); + else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && + ((root_offset != sizeof(struct cramfs_super)) && + (root_offset != 512 + sizeof(struct cramfs_super)))) + { + printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); goto out; } /* Set it all up.. */ - sb->s_op = &cramfs_ops; + sb->s_op = &cramfs_ops; sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root)); retval = sb; - out: return retval; } @@ -205,8 +257,10 @@ { buf->f_type = CRAMFS_MAGIC; buf->f_bsize = PAGE_CACHE_SIZE; + buf->f_blocks = sb->CRAMFS_SB_BLOCKS; buf->f_bfree = 0; buf->f_bavail = 0; + buf->f_files = sb->CRAMFS_SB_FILES; buf->f_ffree = 0; buf->f_namelen = 255; return 0; @@ -271,14 +325,20 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry) { unsigned int offset = 0; + int sorted = dir->i_sb->CRAMFS_SB_FLAGS & CRAMFS_FLAG_SORTED_DIRS; while (offset < dir->i_size) { struct cramfs_inode *de; char *name; - int namelen; + int namelen, retval; de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256); name = (char *)(de+1); + + /* Try to take advantage of sorted directories */ + if (sorted && (dentry->d_name.name[0] < name[0])) + break; + namelen = de->namelen << 2; offset += sizeof(*de) + namelen; @@ -295,10 +355,16 @@ } if (namelen != dentry->d_name.len) continue; - if (memcmp(dentry->d_name.name, name, namelen)) + retval = memcmp(dentry->d_name.name, name, namelen); + if (retval > 0) continue; - d_add(dentry, get_cramfs_inode(dir->i_sb, de)); - return NULL; + if (!retval) { + d_add(dentry, get_cramfs_inode(dir->i_sb, de)); + return NULL; + } + /* else (retval < 0) */ + if (sorted) + break; } d_add(dentry, NULL); return NULL; @@ -308,6 +374,7 @@ { struct inode *inode = page->mapping->host; u32 maxblock, bytes_filled; + void *pgdata; maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; bytes_filled = 0; @@ -321,15 +388,18 @@ start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4); compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset); + pgdata = kmap(page); if (compr_len == 0) ; /* hole */ else - bytes_filled = cramfs_uncompress_block(page_address(page), + bytes_filled = cramfs_uncompress_block(pgdata, PAGE_CACHE_SIZE, cramfs_read(sb, start_offset, compr_len), compr_len); - } - memset(page_address(page) + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); + } else + pgdata = kmap(page); + memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); + kunmap(page); flush_dcache_page(page); SetPageUptodate(page); UnlockPage(page); @@ -376,3 +446,5 @@ module_init(init_cramfs_fs) module_exit(exit_cramfs_fs) +MODULE_LICENSE("GPL"); + Index: uncompress.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/fs/cramfs/uncompress.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- uncompress.c 14 Jan 2001 16:40:11 -0000 1.1.1.1 +++ uncompress.c 9 Apr 2002 13:01:37 -0000 1.2 @@ -16,8 +16,9 @@ */ #include <linux/kernel.h> - -#include "inflate/zlib.h" +#include <linux/errno.h> +#include <linux/vmalloc.h> +#include <linux/zlib_fs.h> static z_stream stream; static int initialized; @@ -33,14 +34,14 @@ stream.next_out = dst; stream.avail_out = dstlen; - err = cramfs_inflateReset(&stream); + err = zlib_fs_inflateReset(&stream); if (err != Z_OK) { - printk("cramfs_inflateReset error %d\n", err); - cramfs_inflateEnd(&stream); - cramfs_inflateInit(&stream); + printk("zlib_fs_inflateReset error %d\n", err); + zlib_fs_inflateEnd(&stream); + zlib_fs_inflateInit(&stream); } - err = cramfs_inflate(&stream, Z_FINISH); + err = zlib_fs_inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) goto err; return stream.total_out; @@ -54,16 +55,23 @@ int cramfs_uncompress_init(void) { if (!initialized++) { + stream.workspace = vmalloc(zlib_fs_inflate_workspacesize()); + if ( !stream.workspace ) { + initialized = 0; + return -ENOMEM; + } stream.next_in = NULL; stream.avail_in = 0; - cramfs_inflateInit(&stream); + zlib_fs_inflateInit(&stream); } return 0; } int cramfs_uncompress_exit(void) { - if (!--initialized) - cramfs_inflateEnd(&stream); + if (!--initialized) { + zlib_fs_inflateEnd(&stream); + vfree(stream.workspace); + } return 0; } --- cramfs.h DELETED --- |