📄 001-squashfs.patch
字号:
+ if (!squashfs_get_cached_block(s, (char *)+ inodep, block, offset,+ sizeof(*inodep), &next_block,+ &next_offset))+ goto failed_read;++ if ((i = squashfs_new_inode(s, inodeb)) == NULL)+ goto failed_read1;++ i->i_nlink = inodep->nlink;+ i->i_mode |= (inodeb->inode_type ==+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :+ S_IFBLK;+ init_special_inode(i, i->i_mode,+ old_decode_dev(inodep->rdev));++ TRACE("Device inode %x:%x, rdev %x\n",+ SQUASHFS_INODE_BLK(inode), offset,+ inodep->rdev);+ break;+ }+ case SQUASHFS_FIFO_TYPE:+ case SQUASHFS_SOCKET_TYPE: {+ struct squashfs_ipc_inode_header *inodep = &id.ipc;+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;++ if (msblk->swap) {+ if (!squashfs_get_cached_block(s, (char *)+ sinodep, block, offset,+ sizeof(*sinodep), &next_block,+ &next_offset))+ goto failed_read;+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);+ } else+ if (!squashfs_get_cached_block(s, (char *)+ inodep, block, offset,+ sizeof(*inodep), &next_block,+ &next_offset))+ goto failed_read;++ if ((i = squashfs_new_inode(s, inodeb)) == NULL)+ goto failed_read1;++ i->i_nlink = inodep->nlink;+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)+ ? S_IFIFO : S_IFSOCK;+ init_special_inode(i, i->i_mode, 0);+ break;+ }+ default:+ ERROR("Unknown inode type %d in squashfs_iget!\n",+ inodeb->inode_type);+ goto failed_read1;+ }++ insert_inode_hash(i);+ return i;++failed_read:+ ERROR("Unable to read inode [%llx:%x]\n", block, offset);++failed_read1:+ return NULL;+}+++static int read_fragment_index_table(struct super_block *s)+{+ struct squashfs_sb_info *msblk = s->s_fs_info;+ struct squashfs_super_block *sblk = &msblk->sblk;++ /* Allocate fragment index table */+ if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES+ (sblk->fragments), GFP_KERNEL))) {+ ERROR("Failed to allocate uid/gid table\n");+ return 0;+ }++ if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&+ !squashfs_read_data(s, (char *)+ msblk->fragment_index,+ sblk->fragment_table_start,+ SQUASHFS_FRAGMENT_INDEX_BYTES+ (sblk->fragments) |+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+ ERROR("unable to read fragment index table\n");+ return 0;+ }++ if (msblk->swap) {+ int i;+ long long fragment;++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments);+ i++) {+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),+ &msblk->fragment_index[i], 1);+ msblk->fragment_index[i] = fragment;+ }+ }++ return 1;+}+++static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)+{+ struct squashfs_super_block *sblk = &msblk->sblk;++ msblk->iget = squashfs_iget;+ msblk->read_blocklist = read_blocklist;+ msblk->read_fragment_index_table = read_fragment_index_table;++ if (sblk->s_major == 1) {+ if (!squashfs_1_0_supported(msblk)) {+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "+ "are unsupported\n");+ SERROR("Please recompile with "+ "Squashfs 1.0 support enabled\n");+ return 0;+ }+ } else if (sblk->s_major == 2) {+ if (!squashfs_2_0_supported(msblk)) {+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "+ "are unsupported\n");+ SERROR("Please recompile with "+ "Squashfs 2.0 support enabled\n");+ return 0;+ }+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >+ SQUASHFS_MINOR) {+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "+ "filesystem\n", sblk->s_major, sblk->s_minor);+ SERROR("Please update your kernel\n");+ return 0;+ }++ return 1;+}+++static int squashfs_fill_super(struct super_block *s, void *data, int silent)+{+ struct squashfs_sb_info *msblk;+ struct squashfs_super_block *sblk;+ int i;+ char b[BDEVNAME_SIZE];+ struct inode *root;++ TRACE("Entered squashfs_read_superblock\n");++ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),+ GFP_KERNEL))) {+ ERROR("Failed to allocate superblock\n");+ goto failure;+ }+ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));+ msblk = s->s_fs_info;+ sblk = &msblk->sblk;++ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);+ msblk->devblksize_log2 = ffz(~msblk->devblksize);++ init_MUTEX(&msblk->read_data_mutex);+ init_MUTEX(&msblk->read_page_mutex);+ init_MUTEX(&msblk->block_cache_mutex);+ init_MUTEX(&msblk->fragment_mutex);+ init_MUTEX(&msblk->meta_index_mutex);++ init_waitqueue_head(&msblk->waitq);+ init_waitqueue_head(&msblk->fragment_wait_queue);++ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,+ sizeof(struct squashfs_super_block) |+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+ SERROR("unable to read superblock\n");+ goto failed_mount;+ }++ /* Check it is a SQUASHFS superblock */+ msblk->swap = 0;+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {+ struct squashfs_super_block ssblk;++ WARNING("Mounting a different endian SQUASHFS "+ "filesystem on %s\n", bdevname(s->s_bdev, b));++ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));+ msblk->swap = 1;+ } else {+ SERROR("Can't find a SQUASHFS superblock on %s\n",+ bdevname(s->s_bdev, b));+ goto failed_mount;+ }+ }++ /* Check the MAJOR & MINOR versions */+ if(!supported_squashfs_filesystem(msblk, silent))+ goto failed_mount;++ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));+ TRACE("Inodes are %scompressed\n",+ SQUASHFS_UNCOMPRESSED_INODES+ (sblk->flags) ? "un" : "");+ TRACE("Data is %scompressed\n",+ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)+ ? "un" : "");+ TRACE("Check data is %s present in the filesystem\n",+ SQUASHFS_CHECK_DATA(sblk->flags) ?+ "" : "not");+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);+ TRACE("Block size %d\n", sblk->block_size);+ TRACE("Number of inodes %d\n", sblk->inodes);+ if (sblk->s_major > 1)+ TRACE("Number of fragments %d\n", sblk->fragments);+ TRACE("Number of uids %d\n", sblk->no_uids);+ TRACE("Number of gids %d\n", sblk->no_guids);+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);+ if (sblk->s_major > 1)+ TRACE("sblk->fragment_table_start %llx\n",+ sblk->fragment_table_start);+ TRACE("sblk->uid_start %llx\n", sblk->uid_start);++ s->s_flags |= MS_RDONLY;+ s->s_op = &squashfs_ops;++ /* Init inode_table block pointer array */+ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *+ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {+ ERROR("Failed to allocate block cache\n");+ goto failed_mount;+ }++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)+ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;++ msblk->next_cache = 0;++ /* Allocate read_data block */+ msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?+ SQUASHFS_METADATA_SIZE :+ sblk->block_size;++ if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {+ ERROR("Failed to allocate read_data block\n");+ goto failed_mount;+ }++ /* Allocate read_page block */+ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {+ ERROR("Failed to allocate read_page block\n");+ goto failed_mount;+ }++ /* Allocate uid and gid tables */+ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *+ sizeof(unsigned int), GFP_KERNEL))) {+ ERROR("Failed to allocate uid/gid table\n");+ goto failed_mount;+ }+ msblk->guid = msblk->uid + sblk->no_uids;++ if (msblk->swap) {+ unsigned int suid[sblk->no_uids + sblk->no_guids];++ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,+ ((sblk->no_uids + sblk->no_guids) *+ sizeof(unsigned int)) |+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+ ERROR("unable to read uid/gid table\n");+ goto failed_mount;+ }++ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids ++ sblk->no_guids), (sizeof(unsigned int) * 8));+ } else+ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,+ ((sblk->no_uids + sblk->no_guids) *+ sizeof(unsigned int)) |+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {+ ERROR("unable to read uid/gid table\n");+ goto failed_mount;+ }+++ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))+ goto allocate_root;++ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *+ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {+ ERROR("Failed to allocate fragment block cache\n");+ goto failed_mount;+ }++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {+ msblk->fragment[i].locked = 0;+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;+ msblk->fragment[i].data = NULL;+ }++ msblk->next_fragment = 0;++ /* Allocate fragment index table */+ if (msblk->read_fragment_index_table(s) == 0)+ goto failed_mount;++allocate_root:+ if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL)+ goto failed_mount;++ if ((s->s_root = d_alloc_root(root)) == NULL) {+ ERROR("Root inode create failed\n");+ iput(root);+ goto failed_mount;+ }++ TRACE("Leaving squashfs_read_super\n");+ return 0;++failed_mount:+ kfree(msblk->fragment_index);+ kfree(msblk->fragment);+ kfree(msblk->uid);+ kfree(msblk->read_page);+ kfree(msblk->read_data);+ kfree(msblk->block_cache);+ kfree(msblk->fragment_index_2);+ kfree(s->s_fs_info);+ s->s_fs_info = NULL;+ return -EINVAL;++failure:+ return -ENOMEM;+}+++static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)+{+ struct squashfs_sb_info *msblk = dentry->d_inode->i_sb->s_fs_info;+ struct squashfs_super_block *sblk = &msblk->sblk;++ TRACE("Entered squashfs_statfs\n");++ buf->f_type = SQUASHFS_MAGIC;+ buf->f_bsize = sblk->block_size;+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;+ buf->f_bfree = buf->f_bavail = 0;+ buf->f_files = sblk->inodes;+ buf->f_ffree = 0;+ buf->f_namelen = SQUASHFS_NAME_LEN;++ return 0;+}+++static int squashfs_symlink_readpage(struct file *file, struct page *page)+{+ struct inode *inode = page->mapping->host;+ int index = page->index << PAGE_CACHE_SHIFT, length, bytes;+ long long block = SQUASHFS_I(inode)->start_block;+ int offset = SQUASHFS_I(inode)->offset;+ void *pageaddr = kmap(page);++ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "+ "%llx, offset %x\n", page->index,+ SQUASHFS_I(inode)->start_block,+ SQUASHFS_I(inode)->offset);++ for (length = 0; length < index; length += bytes) {+ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,+ block, offset, PAGE_CACHE_SIZE, &block,+ &offset))) {+ ERROR("Unable to read symbolic link [%llx:%x]\n", block,+ offset);+ goto skip_read;+ }+ }++ if (length != index) {+ ERROR("(squashfs_symlink_readpage) length != index\n");+ bytes = 0;+ goto skip_read;+ }++ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :+ i_size_read(inode) - length;++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,+ offset, bytes, &block, &offset)))+ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);++skip_read:+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);+ kunmap(page);+ SetPageUptodate(page);+ unlock_page(page);++ return 0;+}+++struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)+{+ struct meta_index *meta = NULL;+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+ int i;++ down(&msblk->meta_index_mutex);++ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);++ if(msblk->meta_index == NULL)+ goto not_allocated;++ for (i = 0; i < SQUASHFS_META_NUMBER; i ++)+ if (msblk->meta_index[i].inode_number == inode->i_ino &&+ msblk->meta_index[i].offset >= offset &&+ msblk->meta_index[i].offset <= index &&+ msblk->meta_index[i].locked == 0) {+ TRACE("locate_meta_index: entry %d, offset %d\n", i,+ msblk->meta_index[i].offset);+ meta = &msblk->meta_index[i];+ offset = meta->offset;+ }++ if (meta)+ meta->locked = 1;++not_allocated:+ up(&msblk->meta_index_mutex);++ return meta;+}+++struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)+{+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;+ struct meta_index *meta = NULL;+ int i;++ down(&msblk->meta_index_mutex);++ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);++ if(msblk->meta_index == NULL) {+ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *+ SQUASHFS_META_NUMBER, GFP_KERNEL))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -