📄 001-squashfs.patch
字号:
Index: linux-2.6.21.7/fs/Kconfig===================================================================--- linux-2.6.21.7.orig/fs/Kconfig+++ linux-2.6.21.7/fs/Kconfig@@ -1371,6 +1371,71 @@ config CRAMFS If unsure, say N. +config SQUASHFS+ tristate "SquashFS 3.0 - Squashed file system support"+ select ZLIB_INFLATE+ help+ Saying Y here includes support for SquashFS 3.0 (a Compressed Read-Only File+ System). Squashfs is a highly compressed read-only filesystem for Linux.+ It uses zlib compression to compress both files, inodes and directories.+ Inodes in the system are very small and all blocks are packed to minimise+ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.+ SquashFS 3.0 supports 64 bit filesystems and files (larger than 4GB), full+ uid/gid information, hard links and timestamps.++ Squashfs is intended for general read-only filesystem use, for archival+ use (i.e. in cases where a .tar.gz file may be used), and in embedded+ systems where low overhead is needed. Further information and filesystem tools+ are available from http://squashfs.sourceforge.net.++ If you want to compile this as a module ( = code which can be+ inserted in and removed from the running kernel whenever you want),+ say M here and read <file:Documentation/modules.txt>. The module+ will be called squashfs. Note that the root file system (the one+ containing the directory /) cannot be compiled as a module.++ If unsure, say N.++config SQUASHFS_EMBEDDED++ bool "Additional options for memory-constrained systems"+ depends on SQUASHFS+ default n+ help+ Saying Y here allows you to specify cache sizes and how Squashfs+ allocates memory. This is only intended for memory constrained+ systems.++ If unsure, say N.++config SQUASHFS_FRAGMENT_CACHE_SIZE+ int "Number of fragments cached" if SQUASHFS_EMBEDDED+ depends on SQUASHFS+ default "3"+ help+ By default SquashFS caches the last 3 fragments read from+ the filesystem. Increasing this amount may mean SquashFS+ has to re-read fragments less often from disk, at the expense+ of extra system memory. Decreasing this amount will mean+ SquashFS uses less memory at the expense of extra reads from disk.++ Note there must be at least one cached fragment. Anything+ much more than three will probably not make much difference.++config SQUASHFS_VMALLOC+ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED+ depends on SQUASHFS+ default n+ help+ By default SquashFS uses kmalloc to obtain fragment cache memory.+ Kmalloc memory is the standard kernel allocator, but it can fail+ on memory constrained systems. Because of the way Vmalloc works,+ Vmalloc can succeed when kmalloc fails. Specifying this option+ will make SquashFS always use Vmalloc to allocate the+ fragment cache memory.++ If unsure, say N.+ config VXFS_FS tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" depends on BLOCKIndex: linux-2.6.21.7/fs/Makefile===================================================================--- linux-2.6.21.7.orig/fs/Makefile+++ linux-2.6.21.7/fs/Makefile@@ -68,6 +68,7 @@ obj-$(CONFIG_JBD) += jbd/ obj-$(CONFIG_JBD2) += jbd2/ obj-$(CONFIG_EXT2_FS) += ext2/ obj-$(CONFIG_CRAMFS) += cramfs/+obj-$(CONFIG_SQUASHFS) += squashfs/ obj-$(CONFIG_RAMFS) += ramfs/ obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ obj-$(CONFIG_CODA_FS) += coda/Index: linux-2.6.21.7/fs/squashfs/inode.c===================================================================--- /dev/null+++ linux-2.6.21.7/fs/squashfs/inode.c@@ -0,0 +1,2124 @@+/*+ * Squashfs - a compressed read only filesystem for Linux+ *+ * Copyright (c) 2002, 2003, 2004, 2005, 2006+ * Phillip Lougher <phillip@lougher.org.uk>+ *+ * This program is free software; you can redistribute it and/or+ * modify it under the terms of the GNU General Public License+ * as published by the Free Software Foundation; either version 2,+ * or (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+ *+ * inode.c+ */++#include <linux/types.h>+#include <linux/squashfs_fs.h>+#include <linux/module.h>+#include <linux/errno.h>+#include <linux/slab.h>+#include <linux/fs.h>+#include <linux/smp_lock.h>+#include <linux/slab.h>+#include <linux/squashfs_fs_sb.h>+#include <linux/squashfs_fs_i.h>+#include <linux/buffer_head.h>+#include <linux/vfs.h>+#include <linux/init.h>+#include <linux/dcache.h>+#include <linux/wait.h>+#include <linux/zlib.h>+#include <linux/blkdev.h>+#include <linux/vmalloc.h>+#include <asm/uaccess.h>+#include <asm/semaphore.h>++#include "squashfs.h"++static void squashfs_put_super(struct super_block *);+static int squashfs_statfs(struct dentry *, struct kstatfs *);+static int squashfs_symlink_readpage(struct file *file, struct page *page);+static int squashfs_readpage(struct file *file, struct page *page);+static int squashfs_readpage4K(struct file *file, struct page *page);+static int squashfs_readdir(struct file *, void *, filldir_t);+static struct inode *squashfs_alloc_inode(struct super_block *sb);+static void squashfs_destroy_inode(struct inode *inode);+static int init_inodecache(void);+static void destroy_inodecache(void);+static struct dentry *squashfs_lookup(struct inode *, struct dentry *,+ struct nameidata *);+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode);+static long long read_blocklist(struct inode *inode, int index,+ int readahead_blks, char *block_list,+ unsigned short **block_p, unsigned int *bsize);+static int squashfs_get_sb(struct file_system_type *, int,+ const char *, void *, struct vfsmount *);+++static z_stream stream;++static struct file_system_type squashfs_fs_type = {+ .owner = THIS_MODULE,+ .name = "squashfs",+ .get_sb = squashfs_get_sb,+ .kill_sb = kill_block_super,+ .fs_flags = FS_REQUIRES_DEV+};++static unsigned char squashfs_filetype_table[] = {+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK+};++static struct super_operations squashfs_ops = {+ .alloc_inode = squashfs_alloc_inode,+ .destroy_inode = squashfs_destroy_inode,+ .statfs = squashfs_statfs,+ .put_super = squashfs_put_super,+};++SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = {+ .readpage = squashfs_symlink_readpage+};++SQSH_EXTERN struct address_space_operations squashfs_aops = {+ .readpage = squashfs_readpage+};++SQSH_EXTERN struct address_space_operations squashfs_aops_4K = {+ .readpage = squashfs_readpage4K+};++static struct file_operations squashfs_dir_ops = {+ .read = generic_read_dir,+ .readdir = squashfs_readdir+};++SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = {+ .lookup = squashfs_lookup+};+++static struct buffer_head *get_block_length(struct super_block *s,+ int *cur_index, int *offset, int *c_byte)+{+ struct squashfs_sb_info *msblk = s->s_fs_info;+ unsigned short temp;+ struct buffer_head *bh;++ if (!(bh = sb_bread(s, *cur_index)))+ goto out;++ if (msblk->devblksize - *offset == 1) {+ if (msblk->swap)+ ((unsigned char *) &temp)[1] = *((unsigned char *)+ (bh->b_data + *offset));+ else+ ((unsigned char *) &temp)[0] = *((unsigned char *)+ (bh->b_data + *offset));+ brelse(bh);+ if (!(bh = sb_bread(s, ++(*cur_index))))+ goto out;+ if (msblk->swap)+ ((unsigned char *) &temp)[0] = *((unsigned char *)+ bh->b_data);+ else+ ((unsigned char *) &temp)[1] = *((unsigned char *)+ bh->b_data);+ *c_byte = temp;+ *offset = 1;+ } else {+ if (msblk->swap) {+ ((unsigned char *) &temp)[1] = *((unsigned char *)+ (bh->b_data + *offset));+ ((unsigned char *) &temp)[0] = *((unsigned char *)+ (bh->b_data + *offset + 1));+ } else {+ ((unsigned char *) &temp)[0] = *((unsigned char *)+ (bh->b_data + *offset));+ ((unsigned char *) &temp)[1] = *((unsigned char *)+ (bh->b_data + *offset + 1));+ }+ *c_byte = temp;+ *offset += 2;+ }++ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {+ if (*offset == msblk->devblksize) {+ brelse(bh);+ if (!(bh = sb_bread(s, ++(*cur_index))))+ goto out;+ *offset = 0;+ }+ if (*((unsigned char *) (bh->b_data + *offset)) !=+ SQUASHFS_MARKER_BYTE) {+ ERROR("Metadata block marker corrupt @ %x\n",+ *cur_index);+ brelse(bh);+ goto out;+ }+ (*offset)++;+ }+ return bh;++out:+ return NULL;+}+++SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,+ long long index, unsigned int length,+ long long *next_index)+{+ struct squashfs_sb_info *msblk = s->s_fs_info;+ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>+ msblk->devblksize_log2) + 2];+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);+ unsigned int cur_index = index >> msblk->devblksize_log2;+ int bytes, avail_bytes, b = 0, k;+ char *c_buffer;+ unsigned int compressed;+ unsigned int c_byte = length;++ if (c_byte) {+ bytes = msblk->devblksize - offset;+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);+ c_buffer = compressed ? msblk->read_data : buffer;+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed+ ? "" : "un", (unsigned int) c_byte);++ if (!(bh[0] = sb_getblk(s, cur_index)))+ goto block_release;++ for (b = 1; bytes < c_byte; b++) {+ if (!(bh[b] = sb_getblk(s, ++cur_index)))+ goto block_release;+ bytes += msblk->devblksize;+ }+ ll_rw_block(READ, b, bh);+ } else {+ if (!(bh[0] = get_block_length(s, &cur_index, &offset,+ &c_byte)))+ goto read_failure;++ bytes = msblk->devblksize - offset;+ compressed = SQUASHFS_COMPRESSED(c_byte);+ c_buffer = compressed ? msblk->read_data : buffer;+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed+ ? "" : "un", (unsigned int) c_byte);++ for (b = 1; bytes < c_byte; b++) {+ if (!(bh[b] = sb_getblk(s, ++cur_index)))+ goto block_release;+ bytes += msblk->devblksize;+ }+ ll_rw_block(READ, b - 1, bh + 1);+ }++ if (compressed)+ down(&msblk->read_data_mutex);++ for (bytes = 0, k = 0; k < b; k++) {+ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?+ msblk->devblksize - offset :+ c_byte - bytes;+ wait_on_buffer(bh[k]);+ if (!buffer_uptodate(bh[k]))+ goto block_release;+ memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes);+ bytes += avail_bytes;+ offset = 0;+ brelse(bh[k]);+ }++ /*+ * uncompress block+ */+ if (compressed) {+ int zlib_err;++ stream.next_in = c_buffer;+ stream.avail_in = c_byte;+ stream.next_out = buffer;+ stream.avail_out = msblk->read_size;++ if (((zlib_err = zlib_inflateInit(&stream)) != Z_OK) ||+ ((zlib_err = zlib_inflate(&stream, Z_FINISH))+ != Z_STREAM_END) || ((zlib_err =+ zlib_inflateEnd(&stream)) != Z_OK)) {+ ERROR("zlib_fs returned unexpected result 0x%x\n",+ zlib_err);+ bytes = 0;+ } else+ bytes = stream.total_out;++ up(&msblk->read_data_mutex);+ }++ if (next_index)+ *next_index = index + c_byte + (length ? 0 :+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags)+ ? 3 : 2));+ return bytes;++block_release:+ while (--b >= 0)+ brelse(bh[b]);++read_failure:+ ERROR("sb_bread failed reading block 0x%x\n", cur_index);+ return 0;+}+++SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,+ long long block, unsigned int offset,+ int length, long long *next_block,+ unsigned int *next_offset)+{+ struct squashfs_sb_info *msblk = s->s_fs_info;+ int n, i, bytes, return_length = length;+ long long next_index;++ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);++ while ( 1 ) {+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)+ if (msblk->block_cache[i].block == block)+ break;++ down(&msblk->block_cache_mutex);++ if (i == SQUASHFS_CACHED_BLKS) {+ /* read inode header block */+ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;+ n ; n --, i = (i + 1) %+ SQUASHFS_CACHED_BLKS)+ if (msblk->block_cache[i].block !=+ SQUASHFS_USED_BLK)+ break;++ if (n == 0) {+ wait_queue_t wait;++ init_waitqueue_entry(&wait, current);+ add_wait_queue(&msblk->waitq, &wait);+ set_current_state(TASK_UNINTERRUPTIBLE);+ up(&msblk->block_cache_mutex);+ schedule();+ set_current_state(TASK_RUNNING);+ remove_wait_queue(&msblk->waitq, &wait);+ continue;+ }+ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;++ if (msblk->block_cache[i].block ==+ SQUASHFS_INVALID_BLK) {+ if (!(msblk->block_cache[i].data =+ kmalloc(SQUASHFS_METADATA_SIZE,+ GFP_KERNEL))) {+ ERROR("Failed to allocate cache"+ "block\n");+ up(&msblk->block_cache_mutex);+ goto out;+ }+ }++ msblk->block_cache[i].block = SQUASHFS_USED_BLK;+ up(&msblk->block_cache_mutex);++ if (!(msblk->block_cache[i].length =+ squashfs_read_data(s,+ msblk->block_cache[i].data,+ block, 0, &next_index))) {+ ERROR("Unable to read cache block [%llx:%x]\n",+ block, offset);+ goto out;+ }++ down(&msblk->block_cache_mutex);+ wake_up(&msblk->waitq);+ msblk->block_cache[i].block = block;+ msblk->block_cache[i].next_index = next_index;+ TRACE("Read cache block [%llx:%x]\n", block, offset);+ }++ if (msblk->block_cache[i].block != block) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -