📄 001-squashfs.patch
字号:
+ long long index_start,+ unsigned int index_offset, int i_count,+ const char *name, int size)+{+ struct squashfs_sb_info *msblk = s->s_fs_info;+ struct squashfs_super_block *sblk = &msblk->sblk;+ int i, length = 0;+ char buffer[sizeof(struct squashfs_dir_index) + SQUASHFS_NAME_LEN + 1];+ struct squashfs_dir_index *index = (struct squashfs_dir_index *) buffer;+ char str[SQUASHFS_NAME_LEN + 1];++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);++ strncpy(str, name, size);+ str[size] = '\0';++ for (i = 0; i < i_count; i++) {+ if (msblk->swap) {+ struct squashfs_dir_index sindex;+ squashfs_get_cached_block(s, (char *) &sindex,+ index_start, index_offset,+ sizeof(sindex), &index_start,+ &index_offset);+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);+ } else+ squashfs_get_cached_block(s, (char *) index,+ index_start, index_offset,+ sizeof(struct squashfs_dir_index),+ &index_start, &index_offset);++ squashfs_get_cached_block(s, index->name, index_start,+ index_offset, index->size + 1,+ &index_start, &index_offset);++ index->name[index->size + 1] = '\0';++ if (strcmp(index->name, str) > 0)+ break;++ length = index->index;+ *next_block = index->start_block + sblk->directory_table_start;+ }++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;+ return length + 3;+}+++static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)+{+ struct inode *i = file->f_dentry->d_inode;+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;+ struct squashfs_super_block *sblk = &msblk->sblk;+ long long next_block = SQUASHFS_I(i)->start_block ++ sblk->directory_table_start;+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,+ dir_count;+ struct squashfs_dir_header dirh;+ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1];+ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;++ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);++ while(file->f_pos < 3) {+ char *name;+ int size, i_ino;++ if(file->f_pos == 0) {+ name = ".";+ size = 1;+ i_ino = i->i_ino;+ } else {+ name = "..";+ size = 2;+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;+ }+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",+ (unsigned int) dirent, name, size, (int)+ file->f_pos, i_ino,+ squashfs_filetype_table[1]);++ if (filldir(dirent, name, size,+ file->f_pos, i_ino,+ squashfs_filetype_table[1]) < 0) {+ TRACE("Filldir returned less than 0\n");+ goto finish;+ }+ file->f_pos += size;+ dirs_read++;+ }++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,+ SQUASHFS_I(i)->u.s2.directory_index_start,+ SQUASHFS_I(i)->u.s2.directory_index_offset,+ SQUASHFS_I(i)->u.s2.directory_index_count,+ file->f_pos);++ while (length < i_size_read(i)) {+ /* read directory header */+ if (msblk->swap) {+ struct squashfs_dir_header sdirh;++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,+ next_block, next_offset, sizeof(sdirh),+ &next_block, &next_offset))+ goto failed_read;++ length += sizeof(sdirh);+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);+ } else {+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,+ next_block, next_offset, sizeof(dirh),+ &next_block, &next_offset))+ goto failed_read;++ length += sizeof(dirh);+ }++ dir_count = dirh.count + 1;+ while (dir_count--) {+ if (msblk->swap) {+ struct squashfs_dir_entry sdire;+ if (!squashfs_get_cached_block(i->i_sb, (char *)+ &sdire, next_block, next_offset,+ sizeof(sdire), &next_block,+ &next_offset))+ goto failed_read;++ length += sizeof(sdire);+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);+ } else {+ if (!squashfs_get_cached_block(i->i_sb, (char *)+ dire, next_block, next_offset,+ sizeof(*dire), &next_block,+ &next_offset))+ goto failed_read;++ length += sizeof(*dire);+ }++ if (!squashfs_get_cached_block(i->i_sb, dire->name,+ next_block, next_offset,+ dire->size + 1, &next_block,+ &next_offset))+ goto failed_read;++ length += dire->size + 1;++ if (file->f_pos >= length)+ continue;++ dire->name[dire->size + 1] = '\0';++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",+ (unsigned int) dirent, dire->name,+ dire->size + 1, (int) file->f_pos,+ dirh.start_block, dire->offset,+ dirh.inode_number + dire->inode_number,+ squashfs_filetype_table[dire->type]);++ if (filldir(dirent, dire->name, dire->size + 1,+ file->f_pos,+ dirh.inode_number + dire->inode_number,+ squashfs_filetype_table[dire->type])+ < 0) {+ TRACE("Filldir returned less than 0\n");+ goto finish;+ }+ file->f_pos = length;+ dirs_read++;+ }+ }++finish:+ return dirs_read;++failed_read:+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,+ next_offset);+ return 0;+}+++static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,+ struct nameidata *nd)+{+ const unsigned char *name = dentry->d_name.name;+ int len = dentry->d_name.len;+ struct inode *inode = NULL;+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;+ struct squashfs_super_block *sblk = &msblk->sblk;+ long long next_block = SQUASHFS_I(i)->start_block ++ sblk->directory_table_start;+ int next_offset = SQUASHFS_I(i)->offset, length = 0,+ dir_count;+ struct squashfs_dir_header dirh;+ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN];+ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);++ if (len > SQUASHFS_NAME_LEN)+ goto exit_loop;++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,+ SQUASHFS_I(i)->u.s2.directory_index_start,+ SQUASHFS_I(i)->u.s2.directory_index_offset,+ SQUASHFS_I(i)->u.s2.directory_index_count, name,+ len);++ while (length < i_size_read(i)) {+ /* read directory header */+ if (msblk->swap) {+ struct squashfs_dir_header sdirh;+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,+ next_block, next_offset, sizeof(sdirh),+ &next_block, &next_offset))+ goto failed_read;++ length += sizeof(sdirh);+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);+ } else {+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,+ next_block, next_offset, sizeof(dirh),+ &next_block, &next_offset))+ goto failed_read;++ length += sizeof(dirh);+ }++ dir_count = dirh.count + 1;+ while (dir_count--) {+ if (msblk->swap) {+ struct squashfs_dir_entry sdire;+ if (!squashfs_get_cached_block(i->i_sb, (char *)+ &sdire, next_block,next_offset,+ sizeof(sdire), &next_block,+ &next_offset))+ goto failed_read;++ length += sizeof(sdire);+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);+ } else {+ if (!squashfs_get_cached_block(i->i_sb, (char *)+ dire, next_block,next_offset,+ sizeof(*dire), &next_block,+ &next_offset))+ goto failed_read;++ length += sizeof(*dire);+ }++ if (!squashfs_get_cached_block(i->i_sb, dire->name,+ next_block, next_offset, dire->size + 1,+ &next_block, &next_offset))+ goto failed_read;++ length += dire->size + 1;++ if (name[0] < dire->name[0])+ goto exit_loop;++ if ((len == dire->size + 1) && !strncmp(name,+ dire->name, len)) {+ squashfs_inode_t ino =+ SQUASHFS_MKINODE(dirh.start_block,+ dire->offset);++ TRACE("calling squashfs_iget for directory "+ "entry %s, inode %x:%x, %d\n", name,+ dirh.start_block, dire->offset,+ dirh.inode_number + dire->inode_number);++ inode = (msblk->iget)(i->i_sb, ino);++ goto exit_loop;+ }+ }+ }++exit_loop:+ d_add(dentry, inode);+ return ERR_PTR(0);++failed_read:+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,+ next_offset);+ goto exit_loop;+}+++static void squashfs_put_super(struct super_block *s)+{+ int i;++ if (s->s_fs_info) {+ struct squashfs_sb_info *sbi = s->s_fs_info;+ if (sbi->block_cache)+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)+ if (sbi->block_cache[i].block !=+ SQUASHFS_INVALID_BLK)+ kfree(sbi->block_cache[i].data);+ if (sbi->fragment)+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)+ SQUASHFS_FREE(sbi->fragment[i].data);+ kfree(sbi->fragment);+ kfree(sbi->block_cache);+ kfree(sbi->read_data);+ kfree(sbi->read_page);+ kfree(sbi->uid);+ kfree(sbi->fragment_index);+ kfree(sbi->fragment_index_2);+ kfree(sbi->meta_index);+ kfree(s->s_fs_info);+ s->s_fs_info = NULL;+ }+}+++static int squashfs_get_sb(struct file_system_type *fs_type,+ int flags, const char *dev_name, void *data,+ struct vfsmount *mnt)+{+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, mnt);+}+++static int __init init_squashfs_fs(void)+{+ int err = init_inodecache();+ if (err)+ goto out;++ printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) "+ "Phillip Lougher\n");++ if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {+ ERROR("Failed to allocate zlib workspace\n");+ destroy_inodecache();+ err = -ENOMEM;+ goto out;+ }++ if ((err = register_filesystem(&squashfs_fs_type))) {+ vfree(stream.workspace);+ destroy_inodecache();+ }++out:+ return err;+}+++static void __exit exit_squashfs_fs(void)+{+ vfree(stream.workspace);+ unregister_filesystem(&squashfs_fs_type);+ destroy_inodecache();+}+++static struct kmem_cache * squashfs_inode_cachep;+++static struct inode *squashfs_alloc_inode(struct super_block *sb)+{+ struct squashfs_inode_info *ei;+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);+ if (!ei)+ return NULL;+ return &ei->vfs_inode;+}+++static void squashfs_destroy_inode(struct inode *inode)+{+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));+}+++static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)+{+ struct squashfs_inode_info *ei = foo;++ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==+ SLAB_CTOR_CONSTRUCTOR)+ inode_init_once(&ei->vfs_inode);+}+++static int __init init_inodecache(void)+{+ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",+ sizeof(struct squashfs_inode_info),+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,+ init_once, NULL);+ if (squashfs_inode_cachep == NULL)+ return -ENOMEM;+ return 0;+}+++static void destroy_inodecache(void)+{+ kmem_cache_destroy(squashfs_inode_cachep);+}+++module_init(init_squashfs_fs);+module_exit(exit_squashfs_fs);+MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem");+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.org.uk>");+MODULE_LICENSE("GPL");Index: linux-2.6.21.7/fs/squashfs/Makefile===================================================================--- /dev/null+++ linux-2.6.21.7/fs/squashfs/Makefile@@ -0,0 +1,7 @@+#+# Makefile for the linux squashfs routines.+#++obj-$(CONFIG_SQUASHFS) += squashfs.o+squashfs-y += inode.o+squashfs-y += squashfs2_0.oIndex: linux-2.6.21.7/fs/squashfs/squashfs2_0.c===================================================================--- /dev/null+++ linux-2.6.21.7/fs/squashfs/squashfs2_0.c@@ -0,0 +1,758 @@+/*+ * 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 p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -