summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/fs/squashfs
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/fs/squashfs')
-rw-r--r--ANDROID_3.4.5/fs/squashfs/Kconfig123
-rw-r--r--ANDROID_3.4.5/fs/squashfs/Makefile11
-rw-r--r--ANDROID_3.4.5/fs/squashfs/block.c211
-rw-r--r--ANDROID_3.4.5/fs/squashfs/cache.c440
-rw-r--r--ANDROID_3.4.5/fs/squashfs/decompressor.c116
-rw-r--r--ANDROID_3.4.5/fs/squashfs/decompressor.h63
-rw-r--r--ANDROID_3.4.5/fs/squashfs/dir.c243
-rw-r--r--ANDROID_3.4.5/fs/squashfs/export.c163
-rw-r--r--ANDROID_3.4.5/fs/squashfs/file.c501
-rw-r--r--ANDROID_3.4.5/fs/squashfs/fragment.c99
-rw-r--r--ANDROID_3.4.5/fs/squashfs/id.c102
-rw-r--r--ANDROID_3.4.5/fs/squashfs/inode.c425
-rw-r--r--ANDROID_3.4.5/fs/squashfs/lzo_wrapper.c135
-rw-r--r--ANDROID_3.4.5/fs/squashfs/namei.c248
-rw-r--r--ANDROID_3.4.5/fs/squashfs/squashfs.h99
-rw-r--r--ANDROID_3.4.5/fs/squashfs/squashfs_fs.h453
-rw-r--r--ANDROID_3.4.5/fs/squashfs/squashfs_fs_i.h54
-rw-r--r--ANDROID_3.4.5/fs/squashfs/squashfs_fs_sb.h80
-rw-r--r--ANDROID_3.4.5/fs/squashfs/super.c500
-rw-r--r--ANDROID_3.4.5/fs/squashfs/symlink.c127
-rw-r--r--ANDROID_3.4.5/fs/squashfs/xattr.c324
-rw-r--r--ANDROID_3.4.5/fs/squashfs/xattr.h47
-rw-r--r--ANDROID_3.4.5/fs/squashfs/xattr_id.c95
-rw-r--r--ANDROID_3.4.5/fs/squashfs/xz_wrapper.c180
-rw-r--r--ANDROID_3.4.5/fs/squashfs/zlib_wrapper.c149
25 files changed, 0 insertions, 4988 deletions
diff --git a/ANDROID_3.4.5/fs/squashfs/Kconfig b/ANDROID_3.4.5/fs/squashfs/Kconfig
deleted file mode 100644
index c70111eb..00000000
--- a/ANDROID_3.4.5/fs/squashfs/Kconfig
+++ /dev/null
@@ -1,123 +0,0 @@
-config SQUASHFS
- tristate "SquashFS 4.0 - Squashed file system support"
- depends on BLOCK
- help
- Saying Y here includes support for SquashFS 4.0 (a Compressed
- Read-Only File System). Squashfs is a highly compressed read-only
- filesystem for Linux. It uses zlib, lzo or xz 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 1 Mbytes
- (default block size 128K). SquashFS 4.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 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. 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_XATTR
- bool "Squashfs XATTR support"
- depends on SQUASHFS
- help
- Saying Y here includes support for extended attributes (xattrs).
- Xattrs are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page).
-
- If unsure, say N.
-
-config SQUASHFS_ZLIB
- bool "Include support for ZLIB compressed file systems"
- depends on SQUASHFS
- select ZLIB_INFLATE
- default y
- help
- ZLIB compression is the standard compression used by Squashfs
- file systems. It offers a good trade-off between compression
- achieved and the amount of CPU time and memory necessary to
- compress and decompress.
-
- If unsure, say Y.
-
-config SQUASHFS_LZO
- bool "Include support for LZO compressed file systems"
- depends on SQUASHFS
- select LZO_DECOMPRESS
- help
- Saying Y here includes support for reading Squashfs file systems
- compressed with LZO compression. LZO compression is mainly
- aimed at embedded systems with slower CPUs where the overheads
- of zlib are too high.
-
- LZO is not the standard compression used in Squashfs and so most
- file systems will be readable without selecting this option.
-
- If unsure, say N.
-
-config SQUASHFS_XZ
- bool "Include support for XZ compressed file systems"
- depends on SQUASHFS
- select XZ_DEC
- help
- Saying Y here includes support for reading Squashfs file systems
- compressed with XZ compression. XZ gives better compression than
- the default zlib compression, at the expense of greater CPU and
- memory overhead.
-
- XZ is not the standard compression used in Squashfs and so most
- file systems will be readable without selecting this option.
-
- If unsure, say N.
-
-config SQUASHFS_4K_DEVBLK_SIZE
- bool "Use 4K device block size?"
- depends on SQUASHFS
- help
- By default Squashfs sets the dev block size (sb_min_blocksize)
- to 1K or the smallest block size supported by the block device
- (if larger). This, because blocks are packed together and
- unaligned in Squashfs, should reduce latency.
-
- This, however, gives poor performance on MTD NAND devices where
- the optimal I/O size is 4K (even though the devices can support
- smaller block sizes).
-
- Using a 4K device block size may also improve overall I/O
- performance for some file access patterns (e.g. sequential
- accesses of files in filesystem order) on all media.
-
- Setting this option will force Squashfs to use a 4K device block
- size by default.
-
- If unsure, say N.
-
-config SQUASHFS_EMBEDDED
- bool "Additional option for memory-constrained systems"
- depends on SQUASHFS
- help
- Saying Y here allows you to specify cache size.
-
- 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.
diff --git a/ANDROID_3.4.5/fs/squashfs/Makefile b/ANDROID_3.4.5/fs/squashfs/Makefile
deleted file mode 100644
index 110b0476..00000000
--- a/ANDROID_3.4.5/fs/squashfs/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux squashfs routines.
-#
-
-obj-$(CONFIG_SQUASHFS) += squashfs.o
-squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
-squashfs-y += namei.o super.o symlink.o decompressor.o
-squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
-squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
-squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
-squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o
diff --git a/ANDROID_3.4.5/fs/squashfs/block.c b/ANDROID_3.4.5/fs/squashfs/block.c
deleted file mode 100644
index fb50652e..00000000
--- a/ANDROID_3.4.5/fs/squashfs/block.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * block.c
- */
-
-/*
- * This file implements the low-level routines to read and decompress
- * datablocks and metadata blocks.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/buffer_head.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-#include "decompressor.h"
-
-/*
- * Read the metadata block length, this is stored in the first two
- * bytes of the metadata block.
- */
-static struct buffer_head *get_block_length(struct super_block *sb,
- u64 *cur_index, int *offset, int *length)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- struct buffer_head *bh;
-
- bh = sb_bread(sb, *cur_index);
- if (bh == NULL)
- return NULL;
-
- if (msblk->devblksize - *offset == 1) {
- *length = (unsigned char) bh->b_data[*offset];
- put_bh(bh);
- bh = sb_bread(sb, ++(*cur_index));
- if (bh == NULL)
- return NULL;
- *length |= (unsigned char) bh->b_data[0] << 8;
- *offset = 1;
- } else {
- *length = (unsigned char) bh->b_data[*offset] |
- (unsigned char) bh->b_data[*offset + 1] << 8;
- *offset += 2;
-
- if (*offset == msblk->devblksize) {
- put_bh(bh);
- bh = sb_bread(sb, ++(*cur_index));
- if (bh == NULL)
- return NULL;
- *offset = 0;
- }
- }
-
- return bh;
-}
-
-
-/*
- * Read and decompress a metadata block or datablock. Length is non-zero
- * if a datablock is being read (the size is stored elsewhere in the
- * filesystem), otherwise the length is obtained from the first two bytes of
- * the metadata block. A bit in the length field indicates if the block
- * is stored uncompressed in the filesystem (usually because compression
- * generated a larger block - this does occasionally happen with compression
- * algorithms).
- */
-int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
- int length, u64 *next_index, int srclength, int pages)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- struct buffer_head **bh;
- int offset = index & ((1 << msblk->devblksize_log2) - 1);
- u64 cur_index = index >> msblk->devblksize_log2;
- int bytes, compressed, b = 0, k = 0, page = 0, avail;
-
- bh = kcalloc(((srclength + msblk->devblksize - 1)
- >> msblk->devblksize_log2) + 1, sizeof(*bh), GFP_KERNEL);
- if (bh == NULL)
- return -ENOMEM;
-
- if (length) {
- /*
- * Datablock.
- */
- bytes = -offset;
- compressed = SQUASHFS_COMPRESSED_BLOCK(length);
- length = SQUASHFS_COMPRESSED_SIZE_BLOCK(length);
- if (next_index)
- *next_index = index + length;
-
- TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n",
- index, compressed ? "" : "un", length, srclength);
-
- if (length < 0 || length > srclength ||
- (index + length) > msblk->bytes_used)
- goto read_failure;
-
- for (b = 0; bytes < length; b++, cur_index++) {
- bh[b] = sb_getblk(sb, cur_index);
- if (bh[b] == NULL)
- goto block_release;
- bytes += msblk->devblksize;
- }
- ll_rw_block(READ, b, bh);
- } else {
- /*
- * Metadata block.
- */
- if ((index + 2) > msblk->bytes_used)
- goto read_failure;
-
- bh[0] = get_block_length(sb, &cur_index, &offset, &length);
- if (bh[0] == NULL)
- goto read_failure;
- b = 1;
-
- bytes = msblk->devblksize - offset;
- compressed = SQUASHFS_COMPRESSED(length);
- length = SQUASHFS_COMPRESSED_SIZE(length);
- if (next_index)
- *next_index = index + length + 2;
-
- TRACE("Block @ 0x%llx, %scompressed size %d\n", index,
- compressed ? "" : "un", length);
-
- if (length < 0 || length > srclength ||
- (index + length) > msblk->bytes_used)
- goto block_release;
-
- for (; bytes < length; b++) {
- bh[b] = sb_getblk(sb, ++cur_index);
- if (bh[b] == NULL)
- goto block_release;
- bytes += msblk->devblksize;
- }
- ll_rw_block(READ, b - 1, bh + 1);
- }
-
- if (compressed) {
- length = squashfs_decompress(msblk, buffer, bh, b, offset,
- length, srclength, pages);
- if (length < 0)
- goto read_failure;
- } else {
- /*
- * Block is uncompressed.
- */
- int i, in, pg_offset = 0;
-
- for (i = 0; i < b; i++) {
- wait_on_buffer(bh[i]);
- if (!buffer_uptodate(bh[i]))
- goto block_release;
- }
-
- for (bytes = length; k < b; k++) {
- in = min(bytes, msblk->devblksize - offset);
- bytes -= in;
- while (in) {
- if (pg_offset == PAGE_CACHE_SIZE) {
- page++;
- pg_offset = 0;
- }
- avail = min_t(int, in, PAGE_CACHE_SIZE -
- pg_offset);
- memcpy(buffer[page] + pg_offset,
- bh[k]->b_data + offset, avail);
- in -= avail;
- pg_offset += avail;
- offset += avail;
- }
- offset = 0;
- put_bh(bh[k]);
- }
- }
-
- kfree(bh);
- return length;
-
-block_release:
- for (; k < b; k++)
- put_bh(bh[k]);
-
-read_failure:
- ERROR("squashfs_read_data failed to read block 0x%llx\n",
- (unsigned long long) index);
- kfree(bh);
- return -EIO;
-}
diff --git a/ANDROID_3.4.5/fs/squashfs/cache.c b/ANDROID_3.4.5/fs/squashfs/cache.c
deleted file mode 100644
index af0b7380..00000000
--- a/ANDROID_3.4.5/fs/squashfs/cache.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * cache.c
- */
-
-/*
- * Blocks in Squashfs are compressed. To avoid repeatedly decompressing
- * recently accessed data Squashfs uses two small metadata and fragment caches.
- *
- * This file implements a generic cache implementation used for both caches,
- * plus functions layered ontop of the generic cache implementation to
- * access the metadata and fragment caches.
- *
- * To avoid out of memory and fragmentation issues with vmalloc the cache
- * uses sequences of kmalloced PAGE_CACHE_SIZE buffers.
- *
- * It should be noted that the cache is not used for file datablocks, these
- * are decompressed and cached in the page-cache in the normal way. The
- * cache is only used to temporarily cache fragment and metadata blocks
- * which have been read as as a result of a metadata (i.e. inode or
- * directory) or fragment access. Because metadata and fragments are packed
- * together into blocks (to gain greater compression) the read of a particular
- * piece of metadata or fragment will retrieve other metadata/fragments which
- * have been packed with it, these because of locality-of-reference may be read
- * in the near future. Temporarily caching them ensures they are available for
- * near future access without requiring an additional read and decompress.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/pagemap.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-
-/*
- * Look-up block in cache, and increment usage count. If not in cache, read
- * and decompress it from disk.
- */
-struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb,
- struct squashfs_cache *cache, u64 block, int length)
-{
- int i, n;
- struct squashfs_cache_entry *entry;
-
- spin_lock(&cache->lock);
-
- while (1) {
- for (i = cache->curr_blk, n = 0; n < cache->entries; n++) {
- if (cache->entry[i].block == block) {
- cache->curr_blk = i;
- break;
- }
- i = (i + 1) % cache->entries;
- }
-
- if (n == cache->entries) {
- /*
- * Block not in cache, if all cache entries are used
- * go to sleep waiting for one to become available.
- */
- if (cache->unused == 0) {
- cache->num_waiters++;
- spin_unlock(&cache->lock);
- wait_event(cache->wait_queue, cache->unused);
- spin_lock(&cache->lock);
- cache->num_waiters--;
- continue;
- }
-
- /*
- * At least one unused cache entry. A simple
- * round-robin strategy is used to choose the entry to
- * be evicted from the cache.
- */
- i = cache->next_blk;
- for (n = 0; n < cache->entries; n++) {
- if (cache->entry[i].refcount == 0)
- break;
- i = (i + 1) % cache->entries;
- }
-
- cache->next_blk = (i + 1) % cache->entries;
- entry = &cache->entry[i];
-
- /*
- * Initialise chosen cache entry, and fill it in from
- * disk.
- */
- cache->unused--;
- entry->block = block;
- entry->refcount = 1;
- entry->pending = 1;
- entry->num_waiters = 0;
- entry->error = 0;
- spin_unlock(&cache->lock);
-
- entry->length = squashfs_read_data(sb, entry->data,
- block, length, &entry->next_index,
- cache->block_size, cache->pages);
-
- spin_lock(&cache->lock);
-
- if (entry->length < 0)
- entry->error = entry->length;
-
- entry->pending = 0;
-
- /*
- * While filling this entry one or more other processes
- * have looked it up in the cache, and have slept
- * waiting for it to become available.
- */
- if (entry->num_waiters) {
- spin_unlock(&cache->lock);
- wake_up_all(&entry->wait_queue);
- } else
- spin_unlock(&cache->lock);
-
- goto out;
- }
-
- /*
- * Block already in cache. Increment refcount so it doesn't
- * get reused until we're finished with it, if it was
- * previously unused there's one less cache entry available
- * for reuse.
- */
- entry = &cache->entry[i];
- if (entry->refcount == 0)
- cache->unused--;
- entry->refcount++;
-
- /*
- * If the entry is currently being filled in by another process
- * go to sleep waiting for it to become available.
- */
- if (entry->pending) {
- entry->num_waiters++;
- spin_unlock(&cache->lock);
- wait_event(entry->wait_queue, !entry->pending);
- } else
- spin_unlock(&cache->lock);
-
- goto out;
- }
-
-out:
- TRACE("Got %s %d, start block %lld, refcount %d, error %d\n",
- cache->name, i, entry->block, entry->refcount, entry->error);
-
- if (entry->error)
- ERROR("Unable to read %s cache entry [%llx]\n", cache->name,
- block);
- return entry;
-}
-
-
-/*
- * Release cache entry, once usage count is zero it can be reused.
- */
-void squashfs_cache_put(struct squashfs_cache_entry *entry)
-{
- struct squashfs_cache *cache = entry->cache;
-
- spin_lock(&cache->lock);
- entry->refcount--;
- if (entry->refcount == 0) {
- cache->unused++;
- /*
- * If there's any processes waiting for a block to become
- * available, wake one up.
- */
- if (cache->num_waiters) {
- spin_unlock(&cache->lock);
- wake_up(&cache->wait_queue);
- return;
- }
- }
- spin_unlock(&cache->lock);
-}
-
-/*
- * Delete cache reclaiming all kmalloced buffers.
- */
-void squashfs_cache_delete(struct squashfs_cache *cache)
-{
- int i, j;
-
- if (cache == NULL)
- return;
-
- for (i = 0; i < cache->entries; i++) {
- if (cache->entry[i].data) {
- for (j = 0; j < cache->pages; j++)
- kfree(cache->entry[i].data[j]);
- kfree(cache->entry[i].data);
- }
- }
-
- kfree(cache->entry);
- kfree(cache);
-}
-
-
-/*
- * Initialise cache allocating the specified number of entries, each of
- * size block_size. To avoid vmalloc fragmentation issues each entry
- * is allocated as a sequence of kmalloced PAGE_CACHE_SIZE buffers.
- */
-struct squashfs_cache *squashfs_cache_init(char *name, int entries,
- int block_size)
-{
- int i, j;
- struct squashfs_cache *cache = kzalloc(sizeof(*cache), GFP_KERNEL);
-
- if (cache == NULL) {
- ERROR("Failed to allocate %s cache\n", name);
- return NULL;
- }
-
- cache->entry = kcalloc(entries, sizeof(*(cache->entry)), GFP_KERNEL);
- if (cache->entry == NULL) {
- ERROR("Failed to allocate %s cache\n", name);
- goto cleanup;
- }
-
- cache->curr_blk = 0;
- cache->next_blk = 0;
- cache->unused = entries;
- cache->entries = entries;
- cache->block_size = block_size;
- cache->pages = block_size >> PAGE_CACHE_SHIFT;
- cache->pages = cache->pages ? cache->pages : 1;
- cache->name = name;
- cache->num_waiters = 0;
- spin_lock_init(&cache->lock);
- init_waitqueue_head(&cache->wait_queue);
-
- for (i = 0; i < entries; i++) {
- struct squashfs_cache_entry *entry = &cache->entry[i];
-
- init_waitqueue_head(&cache->entry[i].wait_queue);
- entry->cache = cache;
- entry->block = SQUASHFS_INVALID_BLK;
- entry->data = kcalloc(cache->pages, sizeof(void *), GFP_KERNEL);
- if (entry->data == NULL) {
- ERROR("Failed to allocate %s cache entry\n", name);
- goto cleanup;
- }
-
- for (j = 0; j < cache->pages; j++) {
- entry->data[j] = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
- if (entry->data[j] == NULL) {
- ERROR("Failed to allocate %s buffer\n", name);
- goto cleanup;
- }
- }
- }
-
- return cache;
-
-cleanup:
- squashfs_cache_delete(cache);
- return NULL;
-}
-
-
-/*
- * Copy up to length bytes from cache entry to buffer starting at offset bytes
- * into the cache entry. If there's not length bytes then copy the number of
- * bytes available. In all cases return the number of bytes copied.
- */
-int squashfs_copy_data(void *buffer, struct squashfs_cache_entry *entry,
- int offset, int length)
-{
- int remaining = length;
-
- if (length == 0)
- return 0;
- else if (buffer == NULL)
- return min(length, entry->length - offset);
-
- while (offset < entry->length) {
- void *buff = entry->data[offset / PAGE_CACHE_SIZE]
- + (offset % PAGE_CACHE_SIZE);
- int bytes = min_t(int, entry->length - offset,
- PAGE_CACHE_SIZE - (offset % PAGE_CACHE_SIZE));
-
- if (bytes >= remaining) {
- memcpy(buffer, buff, remaining);
- remaining = 0;
- break;
- }
-
- memcpy(buffer, buff, bytes);
- buffer += bytes;
- remaining -= bytes;
- offset += bytes;
- }
-
- return length - remaining;
-}
-
-
-/*
- * Read length bytes from metadata position <block, offset> (block is the
- * start of the compressed block on disk, and offset is the offset into
- * the block once decompressed). Data is packed into consecutive blocks,
- * and length bytes may require reading more than one block.
- */
-int squashfs_read_metadata(struct super_block *sb, void *buffer,
- u64 *block, int *offset, int length)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int bytes, res = length;
- struct squashfs_cache_entry *entry;
-
- TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
-
- while (length) {
- entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
- if (entry->error) {
- res = entry->error;
- goto error;
- } else if (*offset >= entry->length) {
- res = -EIO;
- goto error;
- }
-
- bytes = squashfs_copy_data(buffer, entry, *offset, length);
- if (buffer)
- buffer += bytes;
- length -= bytes;
- *offset += bytes;
-
- if (*offset == entry->length) {
- *block = entry->next_index;
- *offset = 0;
- }
-
- squashfs_cache_put(entry);
- }
-
- return res;
-
-error:
- squashfs_cache_put(entry);
- return res;
-}
-
-
-/*
- * Look-up in the fragmment cache the fragment located at <start_block> in the
- * filesystem. If necessary read and decompress it from disk.
- */
-struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *sb,
- u64 start_block, int length)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
-
- return squashfs_cache_get(sb, msblk->fragment_cache, start_block,
- length);
-}
-
-
-/*
- * Read and decompress the datablock located at <start_block> in the
- * filesystem. The cache is used here to avoid duplicating locking and
- * read/decompress code.
- */
-struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb,
- u64 start_block, int length)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
-
- return squashfs_cache_get(sb, msblk->read_page, start_block, length);
-}
-
-
-/*
- * Read a filesystem table (uncompressed sequence of bytes) from disk
- */
-void *squashfs_read_table(struct super_block *sb, u64 block, int length)
-{
- int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- int i, res;
- void *table, *buffer, **data;
-
- table = buffer = kmalloc(length, GFP_KERNEL);
- if (table == NULL)
- return ERR_PTR(-ENOMEM);
-
- data = kcalloc(pages, sizeof(void *), GFP_KERNEL);
- if (data == NULL) {
- res = -ENOMEM;
- goto failed;
- }
-
- for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE)
- data[i] = buffer;
-
- res = squashfs_read_data(sb, data, block, length |
- SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages);
-
- kfree(data);
-
- if (res < 0)
- goto failed;
-
- return table;
-
-failed:
- kfree(table);
- return ERR_PTR(res);
-}
diff --git a/ANDROID_3.4.5/fs/squashfs/decompressor.c b/ANDROID_3.4.5/fs/squashfs/decompressor.c
deleted file mode 100644
index 3f6271d8..00000000
--- a/ANDROID_3.4.5/fs/squashfs/decompressor.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * decompressor.c
- */
-
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/buffer_head.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "decompressor.h"
-#include "squashfs.h"
-
-/*
- * This file (and decompressor.h) implements a decompressor framework for
- * Squashfs, allowing multiple decompressors to be easily supported
- */
-
-static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = {
- NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
-};
-
-#ifndef CONFIG_SQUASHFS_LZO
-static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
- NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
-};
-#endif
-
-#ifndef CONFIG_SQUASHFS_XZ
-static const struct squashfs_decompressor squashfs_xz_comp_ops = {
- NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0
-};
-#endif
-
-#ifndef CONFIG_SQUASHFS_ZLIB
-static const struct squashfs_decompressor squashfs_zlib_comp_ops = {
- NULL, NULL, NULL, ZLIB_COMPRESSION, "zlib", 0
-};
-#endif
-
-static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
- NULL, NULL, NULL, 0, "unknown", 0
-};
-
-static const struct squashfs_decompressor *decompressor[] = {
- &squashfs_zlib_comp_ops,
- &squashfs_lzo_comp_ops,
- &squashfs_xz_comp_ops,
- &squashfs_lzma_unsupported_comp_ops,
- &squashfs_unknown_comp_ops
-};
-
-
-const struct squashfs_decompressor *squashfs_lookup_decompressor(int id)
-{
- int i;
-
- for (i = 0; decompressor[i]->id; i++)
- if (id == decompressor[i]->id)
- break;
-
- return decompressor[i];
-}
-
-
-void *squashfs_decompressor_init(struct super_block *sb, unsigned short flags)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- void *strm, *buffer = NULL;
- int length = 0;
-
- /*
- * Read decompressor specific options from file system if present
- */
- if (SQUASHFS_COMP_OPTS(flags)) {
- buffer = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
- if (buffer == NULL)
- return ERR_PTR(-ENOMEM);
-
- length = squashfs_read_data(sb, &buffer,
- sizeof(struct squashfs_super_block), 0, NULL,
- PAGE_CACHE_SIZE, 1);
-
- if (length < 0) {
- strm = ERR_PTR(length);
- goto finished;
- }
- }
-
- strm = msblk->decompressor->init(msblk, buffer, length);
-
-finished:
- kfree(buffer);
-
- return strm;
-}
diff --git a/ANDROID_3.4.5/fs/squashfs/decompressor.h b/ANDROID_3.4.5/fs/squashfs/decompressor.h
deleted file mode 100644
index 330073e2..00000000
--- a/ANDROID_3.4.5/fs/squashfs/decompressor.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef DECOMPRESSOR_H
-#define DECOMPRESSOR_H
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * decompressor.h
- */
-
-struct squashfs_decompressor {
- void *(*init)(struct squashfs_sb_info *, void *, int);
- void (*free)(void *);
- int (*decompress)(struct squashfs_sb_info *, void **,
- struct buffer_head **, int, int, int, int, int);
- int id;
- char *name;
- int supported;
-};
-
-static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk,
- void *s)
-{
- if (msblk->decompressor)
- msblk->decompressor->free(s);
-}
-
-static inline int squashfs_decompress(struct squashfs_sb_info *msblk,
- void **buffer, struct buffer_head **bh, int b, int offset, int length,
- int srclength, int pages)
-{
- return msblk->decompressor->decompress(msblk, buffer, bh, b, offset,
- length, srclength, pages);
-}
-
-#ifdef CONFIG_SQUASHFS_XZ
-extern const struct squashfs_decompressor squashfs_xz_comp_ops;
-#endif
-
-#ifdef CONFIG_SQUASHFS_LZO
-extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
-#endif
-
-#ifdef CONFIG_SQUASHFS_ZLIB
-extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/fs/squashfs/dir.c b/ANDROID_3.4.5/fs/squashfs/dir.c
deleted file mode 100644
index b381305c..00000000
--- a/ANDROID_3.4.5/fs/squashfs/dir.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * dir.c
- */
-
-/*
- * This file implements code to read directories from disk.
- *
- * See namei.c for a description of directory organisation on disk.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-
-static const unsigned char squashfs_filetype_table[] = {
- DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
-};
-
-/*
- * Lookup offset (f_pos) in the directory index, returning the
- * metadata block containing it.
- *
- * If we get an error reading the index then return the part of the index
- * (if any) we have managed to read - the index isn't essential, just
- * quicker.
- */
-static int get_dir_index_using_offset(struct super_block *sb,
- u64 *next_block, int *next_offset, u64 index_start, int index_offset,
- int i_count, u64 f_pos)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int err, i, index, length = 0;
- struct squashfs_dir_index dir_index;
-
- TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %lld\n",
- i_count, f_pos);
-
- /*
- * Translate from external f_pos to the internal f_pos. This
- * is offset by 3 because we invent "." and ".." entries which are
- * not actually stored in the directory.
- */
- if (f_pos <= 3)
- return f_pos;
- f_pos -= 3;
-
- for (i = 0; i < i_count; i++) {
- err = squashfs_read_metadata(sb, &dir_index, &index_start,
- &index_offset, sizeof(dir_index));
- if (err < 0)
- break;
-
- index = le32_to_cpu(dir_index.index);
- if (index > f_pos)
- /*
- * Found the index we're looking for.
- */
- break;
-
- err = squashfs_read_metadata(sb, NULL, &index_start,
- &index_offset, le32_to_cpu(dir_index.size) + 1);
- if (err < 0)
- break;
-
- length = index;
- *next_block = le32_to_cpu(dir_index.start_block) +
- msblk->directory_table;
- }
-
- *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
-
- /*
- * Translate back from internal f_pos to external f_pos.
- */
- return length + 3;
-}
-
-
-static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
-{
- struct inode *inode = file->f_dentry->d_inode;
- struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- u64 block = squashfs_i(inode)->start + msblk->directory_table;
- int offset = squashfs_i(inode)->offset, length, dir_count, size,
- type, err;
- unsigned int inode_number;
- struct squashfs_dir_header dirh;
- struct squashfs_dir_entry *dire;
-
- TRACE("Entered squashfs_readdir [%llx:%x]\n", block, offset);
-
- dire = kmalloc(sizeof(*dire) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
- if (dire == NULL) {
- ERROR("Failed to allocate squashfs_dir_entry\n");
- goto finish;
- }
-
- /*
- * Return "." and ".." entries as the first two filenames in the
- * directory. To maximise compression these two entries are not
- * stored in the directory, and so we invent them here.
- *
- * It also means that the external f_pos is offset by 3 from the
- * on-disk directory f_pos.
- */
- while (file->f_pos < 3) {
- char *name;
- int i_ino;
-
- if (file->f_pos == 0) {
- name = ".";
- size = 1;
- i_ino = inode->i_ino;
- } else {
- name = "..";
- size = 2;
- i_ino = squashfs_i(inode)->parent;
- }
-
- TRACE("Calling filldir(%p, %s, %d, %lld, %d, %d)\n",
- dirent, name, size, 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;
- }
-
- length = get_dir_index_using_offset(inode->i_sb, &block, &offset,
- squashfs_i(inode)->dir_idx_start,
- squashfs_i(inode)->dir_idx_offset,
- squashfs_i(inode)->dir_idx_cnt,
- file->f_pos);
-
- while (length < i_size_read(inode)) {
- /*
- * Read directory header
- */
- err = squashfs_read_metadata(inode->i_sb, &dirh, &block,
- &offset, sizeof(dirh));
- if (err < 0)
- goto failed_read;
-
- length += sizeof(dirh);
-
- dir_count = le32_to_cpu(dirh.count) + 1;
-
- if (dir_count > SQUASHFS_DIR_COUNT)
- goto failed_read;
-
- while (dir_count--) {
- /*
- * Read directory entry.
- */
- err = squashfs_read_metadata(inode->i_sb, dire, &block,
- &offset, sizeof(*dire));
- if (err < 0)
- goto failed_read;
-
- size = le16_to_cpu(dire->size) + 1;
-
- /* size should never be larger than SQUASHFS_NAME_LEN */
- if (size > SQUASHFS_NAME_LEN)
- goto failed_read;
-
- err = squashfs_read_metadata(inode->i_sb, dire->name,
- &block, &offset, size);
- if (err < 0)
- goto failed_read;
-
- length += sizeof(*dire) + size;
-
- if (file->f_pos >= length)
- continue;
-
- dire->name[size] = '\0';
- inode_number = le32_to_cpu(dirh.inode_number) +
- ((short) le16_to_cpu(dire->inode_number));
- type = le16_to_cpu(dire->type);
-
- TRACE("Calling filldir(%p, %s, %d, %lld, %x:%x, %d, %d)"
- "\n", dirent, dire->name, size,
- file->f_pos,
- le32_to_cpu(dirh.start_block),
- le16_to_cpu(dire->offset),
- inode_number,
- squashfs_filetype_table[type]);
-
- if (filldir(dirent, dire->name, size, file->f_pos,
- inode_number,
- squashfs_filetype_table[type]) < 0) {
- TRACE("Filldir returned less than 0\n");
- goto finish;
- }
-
- file->f_pos = length;
- }
- }
-
-finish:
- kfree(dire);
- return 0;
-
-failed_read:
- ERROR("Unable to read directory block [%llx:%x]\n", block, offset);
- kfree(dire);
- return 0;
-}
-
-
-const struct file_operations squashfs_dir_ops = {
- .read = generic_read_dir,
- .readdir = squashfs_readdir,
- .llseek = default_llseek,
-};
diff --git a/ANDROID_3.4.5/fs/squashfs/export.c b/ANDROID_3.4.5/fs/squashfs/export.c
deleted file mode 100644
index 5e1101ff..00000000
--- a/ANDROID_3.4.5/fs/squashfs/export.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * export.c
- */
-
-/*
- * This file implements code to make Squashfs filesystems exportable (NFS etc.)
- *
- * The export code uses an inode lookup table to map inode numbers passed in
- * filehandles to an inode location on disk. This table is stored compressed
- * into metadata blocks. A second index table is used to locate these. This
- * second index table for speed of access (and because it is small) is read at
- * mount time and cached in memory.
- *
- * The inode lookup table is used only by the export code, inode disk
- * locations are directly encoded in directories, enabling direct access
- * without an intermediate lookup for all operations except the export ops.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/dcache.h>
-#include <linux/exportfs.h>
-#include <linux/slab.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-
-/*
- * Look-up inode number (ino) in table, returning the inode location.
- */
-static long long squashfs_inode_lookup(struct super_block *sb, int ino_num)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int blk = SQUASHFS_LOOKUP_BLOCK(ino_num - 1);
- int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino_num - 1);
- u64 start = le64_to_cpu(msblk->inode_lookup_table[blk]);
- __le64 ino;
- int err;
-
- TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino_num);
-
- err = squashfs_read_metadata(sb, &ino, &start, &offset, sizeof(ino));
- if (err < 0)
- return err;
-
- TRACE("squashfs_inode_lookup, inode = 0x%llx\n",
- (u64) le64_to_cpu(ino));
-
- return le64_to_cpu(ino);
-}
-
-
-static struct dentry *squashfs_export_iget(struct super_block *sb,
- unsigned int ino_num)
-{
- long long ino;
- struct dentry *dentry = ERR_PTR(-ENOENT);
-
- TRACE("Entered squashfs_export_iget\n");
-
- ino = squashfs_inode_lookup(sb, ino_num);
- if (ino >= 0)
- dentry = d_obtain_alias(squashfs_iget(sb, ino, ino_num));
-
- return dentry;
-}
-
-
-static struct dentry *squashfs_fh_to_dentry(struct super_block *sb,
- struct fid *fid, int fh_len, int fh_type)
-{
- if ((fh_type != FILEID_INO32_GEN && fh_type != FILEID_INO32_GEN_PARENT)
- || fh_len < 2)
- return NULL;
-
- return squashfs_export_iget(sb, fid->i32.ino);
-}
-
-
-static struct dentry *squashfs_fh_to_parent(struct super_block *sb,
- struct fid *fid, int fh_len, int fh_type)
-{
- if (fh_type != FILEID_INO32_GEN_PARENT || fh_len < 4)
- return NULL;
-
- return squashfs_export_iget(sb, fid->i32.parent_ino);
-}
-
-
-static struct dentry *squashfs_get_parent(struct dentry *child)
-{
- struct inode *inode = child->d_inode;
- unsigned int parent_ino = squashfs_i(inode)->parent;
-
- return squashfs_export_iget(inode->i_sb, parent_ino);
-}
-
-
-/*
- * Read uncompressed inode lookup table indexes off disk into memory
- */
-__le64 *squashfs_read_inode_lookup_table(struct super_block *sb,
- u64 lookup_table_start, u64 next_table, unsigned int inodes)
-{
- unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(inodes);
- __le64 *table;
-
- TRACE("In read_inode_lookup_table, length %d\n", length);
-
- /* Sanity check values */
-
- /* there should always be at least one inode */
- if (inodes == 0)
- return ERR_PTR(-EINVAL);
-
- /* length bytes should not extend into the next table - this check
- * also traps instances where lookup_table_start is incorrectly larger
- * than the next table start
- */
- if (lookup_table_start + length > next_table)
- return ERR_PTR(-EINVAL);
-
- table = squashfs_read_table(sb, lookup_table_start, length);
-
- /*
- * table[0] points to the first inode lookup table metadata block,
- * this should be less than lookup_table_start
- */
- if (!IS_ERR(table) && le64_to_cpu(table[0]) >= lookup_table_start) {
- kfree(table);
- return ERR_PTR(-EINVAL);
- }
-
- return table;
-}
-
-
-const struct export_operations squashfs_export_ops = {
- .fh_to_dentry = squashfs_fh_to_dentry,
- .fh_to_parent = squashfs_fh_to_parent,
- .get_parent = squashfs_get_parent
-};
diff --git a/ANDROID_3.4.5/fs/squashfs/file.c b/ANDROID_3.4.5/fs/squashfs/file.c
deleted file mode 100644
index 8ca62c28..00000000
--- a/ANDROID_3.4.5/fs/squashfs/file.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * file.c
- */
-
-/*
- * This file contains code for handling regular files. A regular file
- * consists of a sequence of contiguous compressed blocks, and/or a
- * compressed fragment block (tail-end packed block). The compressed size
- * of each datablock is stored in a block list contained within the
- * file inode (itself stored in one or more compressed metadata blocks).
- *
- * To speed up access to datablocks when reading 'large' files (256 Mbytes or
- * larger), the code implements an index cache that caches the mapping from
- * block index to datablock location on disk.
- *
- * The index cache allows Squashfs to handle large files (up to 1.75 TiB) while
- * retaining a simple and space-efficient block list on disk. The cache
- * is split into slots, caching up to eight 224 GiB files (128 KiB blocks).
- * Larger files use multiple slots, with 1.75 TiB files using all 8 slots.
- * The index cache is designed to be memory efficient, and by default uses
- * 16 KiB.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/pagemap.h>
-#include <linux/mutex.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-
-/*
- * Locate cache slot in range [offset, index] for specified inode. If
- * there's more than one return the slot closest to index.
- */
-static struct meta_index *locate_meta_index(struct inode *inode, int offset,
- int index)
-{
- struct meta_index *meta = NULL;
- struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- int i;
-
- mutex_lock(&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_SLOTS; 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:
- mutex_unlock(&msblk->meta_index_mutex);
-
- return meta;
-}
-
-
-/*
- * Find and initialise an empty cache slot for index offset.
- */
-static 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;
-
- mutex_lock(&msblk->meta_index_mutex);
-
- TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
-
- if (msblk->meta_index == NULL) {
- /*
- * First time cache index has been used, allocate and
- * initialise. The cache index could be allocated at
- * mount time but doing it here means it is allocated only
- * if a 'large' file is read.
- */
- msblk->meta_index = kcalloc(SQUASHFS_META_SLOTS,
- sizeof(*(msblk->meta_index)), GFP_KERNEL);
- if (msblk->meta_index == NULL) {
- ERROR("Failed to allocate meta_index\n");
- goto failed;
- }
- for (i = 0; i < SQUASHFS_META_SLOTS; i++) {
- msblk->meta_index[i].inode_number = 0;
- msblk->meta_index[i].locked = 0;
- }
- msblk->next_meta_index = 0;
- }
-
- for (i = SQUASHFS_META_SLOTS; i &&
- msblk->meta_index[msblk->next_meta_index].locked; i--)
- msblk->next_meta_index = (msblk->next_meta_index + 1) %
- SQUASHFS_META_SLOTS;
-
- if (i == 0) {
- TRACE("empty_meta_index: failed!\n");
- goto failed;
- }
-
- TRACE("empty_meta_index: returned meta entry %d, %p\n",
- msblk->next_meta_index,
- &msblk->meta_index[msblk->next_meta_index]);
-
- meta = &msblk->meta_index[msblk->next_meta_index];
- msblk->next_meta_index = (msblk->next_meta_index + 1) %
- SQUASHFS_META_SLOTS;
-
- meta->inode_number = inode->i_ino;
- meta->offset = offset;
- meta->skip = skip;
- meta->entries = 0;
- meta->locked = 1;
-
-failed:
- mutex_unlock(&msblk->meta_index_mutex);
- return meta;
-}
-
-
-static void release_meta_index(struct inode *inode, struct meta_index *meta)
-{
- struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- mutex_lock(&msblk->meta_index_mutex);
- meta->locked = 0;
- mutex_unlock(&msblk->meta_index_mutex);
-}
-
-
-/*
- * Read the next n blocks from the block list, starting from
- * metadata block <start_block, offset>.
- */
-static long long read_indexes(struct super_block *sb, int n,
- u64 *start_block, int *offset)
-{
- int err, i;
- long long block = 0;
- __le32 *blist = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
-
- if (blist == NULL) {
- ERROR("read_indexes: Failed to allocate block_list\n");
- return -ENOMEM;
- }
-
- while (n) {
- int blocks = min_t(int, n, PAGE_CACHE_SIZE >> 2);
-
- err = squashfs_read_metadata(sb, blist, start_block,
- offset, blocks << 2);
- if (err < 0) {
- ERROR("read_indexes: reading block [%llx:%x]\n",
- *start_block, *offset);
- goto failure;
- }
-
- for (i = 0; i < blocks; i++) {
- int size = le32_to_cpu(blist[i]);
- block += SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
- }
- n -= blocks;
- }
-
- kfree(blist);
- return block;
-
-failure:
- kfree(blist);
- return err;
-}
-
-
-/*
- * Each cache index slot has SQUASHFS_META_ENTRIES, each of which
- * can cache one index -> datablock/blocklist-block mapping. We wish
- * to distribute these over the length of the file, entry[0] maps index x,
- * entry[1] maps index x + skip, entry[2] maps index x + 2 * skip, and so on.
- * The larger the file, the greater the skip factor. The skip factor is
- * limited to the size of the metadata cache (SQUASHFS_CACHED_BLKS) to ensure
- * the number of metadata blocks that need to be read fits into the cache.
- * If the skip factor is limited in this way then the file will use multiple
- * slots.
- */
-static inline int calculate_skip(int blocks)
-{
- int skip = blocks / ((SQUASHFS_META_ENTRIES + 1)
- * SQUASHFS_META_INDEXES);
- return min(SQUASHFS_CACHED_BLKS - 1, skip + 1);
-}
-
-
-/*
- * Search and grow the index cache for the specified inode, returning the
- * on-disk locations of the datablock and block list metadata block
- * <index_block, index_offset> for index (scaled to nearest cache index).
- */
-static int fill_meta_index(struct inode *inode, int index,
- u64 *index_block, int *index_offset, u64 *data_block)
-{
- struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- int skip = calculate_skip(i_size_read(inode) >> msblk->block_log);
- int offset = 0;
- struct meta_index *meta;
- struct meta_entry *meta_entry;
- u64 cur_index_block = squashfs_i(inode)->block_list_start;
- int cur_offset = squashfs_i(inode)->offset;
- u64 cur_data_block = squashfs_i(inode)->start;
- int err, i;
-
- /*
- * Scale index to cache index (cache slot entry)
- */
- index /= SQUASHFS_META_INDEXES * skip;
-
- while (offset < index) {
- meta = locate_meta_index(inode, offset + 1, index);
-
- if (meta == NULL) {
- meta = empty_meta_index(inode, offset + 1, skip);
- if (meta == NULL)
- goto all_done;
- } else {
- offset = index < meta->offset + meta->entries ? index :
- meta->offset + meta->entries - 1;
- meta_entry = &meta->meta_entry[offset - meta->offset];
- cur_index_block = meta_entry->index_block +
- msblk->inode_table;
- cur_offset = meta_entry->offset;
- cur_data_block = meta_entry->data_block;
- TRACE("get_meta_index: offset %d, meta->offset %d, "
- "meta->entries %d\n", offset, meta->offset,
- meta->entries);
- TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
- " data_block 0x%llx\n", cur_index_block,
- cur_offset, cur_data_block);
- }
-
- /*
- * If necessary grow cache slot by reading block list. Cache
- * slot is extended up to index or to the end of the slot, in
- * which case further slots will be used.
- */
- for (i = meta->offset + meta->entries; i <= index &&
- i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
- int blocks = skip * SQUASHFS_META_INDEXES;
- long long res = read_indexes(inode->i_sb, blocks,
- &cur_index_block, &cur_offset);
-
- if (res < 0) {
- if (meta->entries == 0)
- /*
- * Don't leave an empty slot on read
- * error allocated to this inode...
- */
- meta->inode_number = 0;
- err = res;
- goto failed;
- }
-
- cur_data_block += res;
- meta_entry = &meta->meta_entry[i - meta->offset];
- meta_entry->index_block = cur_index_block -
- msblk->inode_table;
- meta_entry->offset = cur_offset;
- meta_entry->data_block = cur_data_block;
- meta->entries++;
- offset++;
- }
-
- TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
- meta->offset, meta->entries);
-
- release_meta_index(inode, meta);
- }
-
-all_done:
- *index_block = cur_index_block;
- *index_offset = cur_offset;
- *data_block = cur_data_block;
-
- /*
- * Scale cache index (cache slot entry) to index
- */
- return offset * SQUASHFS_META_INDEXES * skip;
-
-failed:
- release_meta_index(inode, meta);
- return err;
-}
-
-
-/*
- * Get the on-disk location and compressed size of the datablock
- * specified by index. Fill_meta_index() does most of the work.
- */
-static int read_blocklist(struct inode *inode, int index, u64 *block)
-{
- u64 start;
- long long blks;
- int offset;
- __le32 size;
- int res = fill_meta_index(inode, index, &start, &offset, block);
-
- TRACE("read_blocklist: res %d, index %d, start 0x%llx, offset"
- " 0x%x, block 0x%llx\n", res, index, start, offset,
- *block);
-
- if (res < 0)
- return res;
-
- /*
- * res contains the index of the mapping returned by fill_meta_index(),
- * this will likely be less than the desired index (because the
- * meta_index cache works at a higher granularity). Read any
- * extra block indexes needed.
- */
- if (res < index) {
- blks = read_indexes(inode->i_sb, index - res, &start, &offset);
- if (blks < 0)
- return (int) blks;
- *block += blks;
- }
-
- /*
- * Read length of block specified by index.
- */
- res = squashfs_read_metadata(inode->i_sb, &size, &start, &offset,
- sizeof(size));
- if (res < 0)
- return res;
- return le32_to_cpu(size);
-}
-
-
-static int squashfs_readpage(struct file *file, struct page *page)
-{
- struct inode *inode = page->mapping->host;
- struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- int bytes, i, offset = 0, sparse = 0;
- struct squashfs_cache_entry *buffer = NULL;
- void *pageaddr;
-
- int mask = (1 << (msblk->block_log - PAGE_CACHE_SHIFT)) - 1;
- int index = page->index >> (msblk->block_log - PAGE_CACHE_SHIFT);
- int start_index = page->index & ~mask;
- int end_index = start_index | mask;
- int file_end = i_size_read(inode) >> msblk->block_log;
-
- TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
- page->index, squashfs_i(inode)->start);
-
- if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
- PAGE_CACHE_SHIFT))
- goto out;
-
- if (index < file_end || squashfs_i(inode)->fragment_block ==
- SQUASHFS_INVALID_BLK) {
- /*
- * Reading a datablock from disk. Need to read block list
- * to get location and block size.
- */
- u64 block = 0;
- int bsize = read_blocklist(inode, index, &block);
- if (bsize < 0)
- goto error_out;
-
- if (bsize == 0) { /* hole */
- bytes = index == file_end ?
- (i_size_read(inode) & (msblk->block_size - 1)) :
- msblk->block_size;
- sparse = 1;
- } else {
- /*
- * Read and decompress datablock.
- */
- buffer = squashfs_get_datablock(inode->i_sb,
- block, bsize);
- if (buffer->error) {
- ERROR("Unable to read page, block %llx, size %x"
- "\n", block, bsize);
- squashfs_cache_put(buffer);
- goto error_out;
- }
- bytes = buffer->length;
- }
- } else {
- /*
- * Datablock is stored inside a fragment (tail-end packed
- * block).
- */
- buffer = squashfs_get_fragment(inode->i_sb,
- squashfs_i(inode)->fragment_block,
- squashfs_i(inode)->fragment_size);
-
- if (buffer->error) {
- ERROR("Unable to read page, block %llx, size %x\n",
- squashfs_i(inode)->fragment_block,
- squashfs_i(inode)->fragment_size);
- squashfs_cache_put(buffer);
- goto error_out;
- }
- bytes = i_size_read(inode) & (msblk->block_size - 1);
- offset = squashfs_i(inode)->fragment_offset;
- }
-
- /*
- * Loop copying datablock into pages. As the datablock likely covers
- * many PAGE_CACHE_SIZE pages (default block size is 128 KiB) explicitly
- * grab the pages from the page cache, except for the page that we've
- * been called to fill.
- */
- for (i = start_index; i <= end_index && bytes > 0; i++,
- bytes -= PAGE_CACHE_SIZE, offset += PAGE_CACHE_SIZE) {
- struct page *push_page;
- int avail = sparse ? 0 : min_t(int, bytes, PAGE_CACHE_SIZE);
-
- TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail);
-
- push_page = (i == page->index) ? page :
- grab_cache_page_nowait(page->mapping, i);
-
- if (!push_page)
- continue;
-
- if (PageUptodate(push_page))
- goto skip_page;
-
- pageaddr = kmap_atomic(push_page);
- squashfs_copy_data(pageaddr, buffer, offset, avail);
- memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
- kunmap_atomic(pageaddr);
- flush_dcache_page(push_page);
- SetPageUptodate(push_page);
-skip_page:
- unlock_page(push_page);
- if (i != page->index)
- page_cache_release(push_page);
- }
-
- if (!sparse)
- squashfs_cache_put(buffer);
-
- return 0;
-
-error_out:
- SetPageError(page);
-out:
- pageaddr = kmap_atomic(page);
- memset(pageaddr, 0, PAGE_CACHE_SIZE);
- kunmap_atomic(pageaddr);
- flush_dcache_page(page);
- if (!PageError(page))
- SetPageUptodate(page);
- unlock_page(page);
-
- return 0;
-}
-
-
-const struct address_space_operations squashfs_aops = {
- .readpage = squashfs_readpage
-};
diff --git a/ANDROID_3.4.5/fs/squashfs/fragment.c b/ANDROID_3.4.5/fs/squashfs/fragment.c
deleted file mode 100644
index 0ed6edbc..00000000
--- a/ANDROID_3.4.5/fs/squashfs/fragment.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * fragment.c
- */
-
-/*
- * This file implements code to handle compressed fragments (tail-end packed
- * datablocks).
- *
- * Regular files contain a fragment index which is mapped to a fragment
- * location on disk and compressed size using a fragment lookup table.
- * Like everything in Squashfs this fragment lookup table is itself stored
- * compressed into metadata blocks. A second index table is used to locate
- * these. This second index table for speed of access (and because it
- * is small) is read at mount time and cached in memory.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-
-/*
- * Look-up fragment using the fragment index table. Return the on disk
- * location of the fragment and its compressed size
- */
-int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
- u64 *fragment_block)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int block = SQUASHFS_FRAGMENT_INDEX(fragment);
- int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
- u64 start_block = le64_to_cpu(msblk->fragment_index[block]);
- struct squashfs_fragment_entry fragment_entry;
- int size;
-
- size = squashfs_read_metadata(sb, &fragment_entry, &start_block,
- &offset, sizeof(fragment_entry));
- if (size < 0)
- return size;
-
- *fragment_block = le64_to_cpu(fragment_entry.start_block);
- size = le32_to_cpu(fragment_entry.size);
-
- return size;
-}
-
-
-/*
- * Read the uncompressed fragment lookup table indexes off disk into memory
- */
-__le64 *squashfs_read_fragment_index_table(struct super_block *sb,
- u64 fragment_table_start, u64 next_table, unsigned int fragments)
-{
- unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments);
- __le64 *table;
-
- /*
- * Sanity check, length bytes should not extend into the next table -
- * this check also traps instances where fragment_table_start is
- * incorrectly larger than the next table start
- */
- if (fragment_table_start + length > next_table)
- return ERR_PTR(-EINVAL);
-
- table = squashfs_read_table(sb, fragment_table_start, length);
-
- /*
- * table[0] points to the first fragment table metadata block, this
- * should be less than fragment_table_start
- */
- if (!IS_ERR(table) && le64_to_cpu(table[0]) >= fragment_table_start) {
- kfree(table);
- return ERR_PTR(-EINVAL);
- }
-
- return table;
-}
diff --git a/ANDROID_3.4.5/fs/squashfs/id.c b/ANDROID_3.4.5/fs/squashfs/id.c
deleted file mode 100644
index d38ea3da..00000000
--- a/ANDROID_3.4.5/fs/squashfs/id.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * id.c
- */
-
-/*
- * This file implements code to handle uids and gids.
- *
- * For space efficiency regular files store uid and gid indexes, which are
- * converted to 32-bit uids/gids using an id look up table. This table is
- * stored compressed into metadata blocks. A second index table is used to
- * locate these. This second index table for speed of access (and because it
- * is small) is read at mount time and cached in memory.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-
-/*
- * Map uid/gid index into real 32-bit uid/gid using the id look up table
- */
-int squashfs_get_id(struct super_block *sb, unsigned int index,
- unsigned int *id)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int block = SQUASHFS_ID_BLOCK(index);
- int offset = SQUASHFS_ID_BLOCK_OFFSET(index);
- u64 start_block = le64_to_cpu(msblk->id_table[block]);
- __le32 disk_id;
- int err;
-
- err = squashfs_read_metadata(sb, &disk_id, &start_block, &offset,
- sizeof(disk_id));
- if (err < 0)
- return err;
-
- *id = le32_to_cpu(disk_id);
- return 0;
-}
-
-
-/*
- * Read uncompressed id lookup table indexes from disk into memory
- */
-__le64 *squashfs_read_id_index_table(struct super_block *sb,
- u64 id_table_start, u64 next_table, unsigned short no_ids)
-{
- unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids);
- __le64 *table;
-
- TRACE("In read_id_index_table, length %d\n", length);
-
- /* Sanity check values */
-
- /* there should always be at least one id */
- if (no_ids == 0)
- return ERR_PTR(-EINVAL);
-
- /*
- * length bytes should not extend into the next table - this check
- * also traps instances where id_table_start is incorrectly larger
- * than the next table start
- */
- if (id_table_start + length > next_table)
- return ERR_PTR(-EINVAL);
-
- table = squashfs_read_table(sb, id_table_start, length);
-
- /*
- * table[0] points to the first id lookup table metadata block, this
- * should be less than id_table_start
- */
- if (!IS_ERR(table) && le64_to_cpu(table[0]) >= id_table_start) {
- kfree(table);
- return ERR_PTR(-EINVAL);
- }
-
- return table;
-}
diff --git a/ANDROID_3.4.5/fs/squashfs/inode.c b/ANDROID_3.4.5/fs/squashfs/inode.c
deleted file mode 100644
index 81afbccf..00000000
--- a/ANDROID_3.4.5/fs/squashfs/inode.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * inode.c
- */
-
-/*
- * This file implements code to create and read inodes from disk.
- *
- * Inodes in Squashfs are identified by a 48-bit inode which encodes the
- * location of the compressed metadata block containing the inode, and the byte
- * offset into that block where the inode is placed (<block, offset>).
- *
- * To maximise compression there are different inodes for each file type
- * (regular file, directory, device, etc.), the inode contents and length
- * varying with the type.
- *
- * To further maximise compression, two types of regular file inode and
- * directory inode are defined: inodes optimised for frequently occurring
- * regular files and directories, and extended types where extra
- * information has to be stored.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/xattr.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-#include "xattr.h"
-
-/*
- * Initialise VFS inode with the base inode information common to all
- * Squashfs inode types. Sqsh_ino contains the unswapped base inode
- * off disk.
- */
-static int squashfs_new_inode(struct super_block *sb, struct inode *inode,
- struct squashfs_base_inode *sqsh_ino)
-{
- int err;
-
- err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &inode->i_uid);
- if (err)
- return err;
-
- err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &inode->i_gid);
- if (err)
- return err;
-
- inode->i_ino = le32_to_cpu(sqsh_ino->inode_number);
- inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime);
- inode->i_atime.tv_sec = inode->i_mtime.tv_sec;
- inode->i_ctime.tv_sec = inode->i_mtime.tv_sec;
- inode->i_mode = le16_to_cpu(sqsh_ino->mode);
- inode->i_size = 0;
-
- return err;
-}
-
-
-struct inode *squashfs_iget(struct super_block *sb, long long ino,
- unsigned int ino_number)
-{
- struct inode *inode = iget_locked(sb, ino_number);
- int err;
-
- TRACE("Entered squashfs_iget\n");
-
- if (!inode)
- return ERR_PTR(-ENOMEM);
- if (!(inode->i_state & I_NEW))
- return inode;
-
- err = squashfs_read_inode(inode, ino);
- if (err) {
- iget_failed(inode);
- return ERR_PTR(err);
- }
-
- unlock_new_inode(inode);
- return inode;
-}
-
-
-/*
- * Initialise VFS inode by reading inode from inode table (compressed
- * metadata). The format and amount of data read depends on type.
- */
-int squashfs_read_inode(struct inode *inode, long long ino)
-{
- struct super_block *sb = inode->i_sb;
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- u64 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table;
- int err, type, offset = SQUASHFS_INODE_OFFSET(ino);
- union squashfs_inode squashfs_ino;
- struct squashfs_base_inode *sqshb_ino = &squashfs_ino.base;
- int xattr_id = SQUASHFS_INVALID_XATTR;
-
- TRACE("Entered squashfs_read_inode\n");
-
- /*
- * Read inode base common to all inode types.
- */
- err = squashfs_read_metadata(sb, sqshb_ino, &block,
- &offset, sizeof(*sqshb_ino));
- if (err < 0)
- goto failed_read;
-
- err = squashfs_new_inode(sb, inode, sqshb_ino);
- if (err)
- goto failed_read;
-
- block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table;
- offset = SQUASHFS_INODE_OFFSET(ino);
-
- type = le16_to_cpu(sqshb_ino->inode_type);
- switch (type) {
- case SQUASHFS_REG_TYPE: {
- unsigned int frag_offset, frag;
- int frag_size;
- u64 frag_blk;
- struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- frag = le32_to_cpu(sqsh_ino->fragment);
- if (frag != SQUASHFS_INVALID_FRAG) {
- frag_offset = le32_to_cpu(sqsh_ino->offset);
- frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
- if (frag_size < 0) {
- err = frag_size;
- goto failed_read;
- }
- } else {
- frag_blk = SQUASHFS_INVALID_BLK;
- frag_size = 0;
- frag_offset = 0;
- }
-
- set_nlink(inode, 1);
- inode->i_size = le32_to_cpu(sqsh_ino->file_size);
- inode->i_fop = &generic_ro_fops;
- inode->i_mode |= S_IFREG;
- inode->i_blocks = ((inode->i_size - 1) >> 9) + 1;
- squashfs_i(inode)->fragment_block = frag_blk;
- squashfs_i(inode)->fragment_size = frag_size;
- squashfs_i(inode)->fragment_offset = frag_offset;
- squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
- squashfs_i(inode)->block_list_start = block;
- squashfs_i(inode)->offset = offset;
- inode->i_data.a_ops = &squashfs_aops;
-
- TRACE("File inode %x:%x, start_block %llx, block_list_start "
- "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino),
- offset, squashfs_i(inode)->start, block, offset);
- break;
- }
- case SQUASHFS_LREG_TYPE: {
- unsigned int frag_offset, frag;
- int frag_size;
- u64 frag_blk;
- struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- frag = le32_to_cpu(sqsh_ino->fragment);
- if (frag != SQUASHFS_INVALID_FRAG) {
- frag_offset = le32_to_cpu(sqsh_ino->offset);
- frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
- if (frag_size < 0) {
- err = frag_size;
- goto failed_read;
- }
- } else {
- frag_blk = SQUASHFS_INVALID_BLK;
- frag_size = 0;
- frag_offset = 0;
- }
-
- xattr_id = le32_to_cpu(sqsh_ino->xattr);
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- inode->i_size = le64_to_cpu(sqsh_ino->file_size);
- inode->i_op = &squashfs_inode_ops;
- inode->i_fop = &generic_ro_fops;
- inode->i_mode |= S_IFREG;
- inode->i_blocks = (inode->i_size -
- le64_to_cpu(sqsh_ino->sparse) + 511) >> 9;
-
- squashfs_i(inode)->fragment_block = frag_blk;
- squashfs_i(inode)->fragment_size = frag_size;
- squashfs_i(inode)->fragment_offset = frag_offset;
- squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block);
- squashfs_i(inode)->block_list_start = block;
- squashfs_i(inode)->offset = offset;
- inode->i_data.a_ops = &squashfs_aops;
-
- TRACE("File inode %x:%x, start_block %llx, block_list_start "
- "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino),
- offset, squashfs_i(inode)->start, block, offset);
- break;
- }
- case SQUASHFS_DIR_TYPE: {
- struct squashfs_dir_inode *sqsh_ino = &squashfs_ino.dir;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- inode->i_size = le16_to_cpu(sqsh_ino->file_size);
- inode->i_op = &squashfs_dir_inode_ops;
- inode->i_fop = &squashfs_dir_ops;
- inode->i_mode |= S_IFDIR;
- squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
- squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset);
- squashfs_i(inode)->dir_idx_cnt = 0;
- squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode);
-
- TRACE("Directory inode %x:%x, start_block %llx, offset %x\n",
- SQUASHFS_INODE_BLK(ino), offset,
- squashfs_i(inode)->start,
- le16_to_cpu(sqsh_ino->offset));
- break;
- }
- case SQUASHFS_LDIR_TYPE: {
- struct squashfs_ldir_inode *sqsh_ino = &squashfs_ino.ldir;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- xattr_id = le32_to_cpu(sqsh_ino->xattr);
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- inode->i_size = le32_to_cpu(sqsh_ino->file_size);
- inode->i_op = &squashfs_dir_inode_ops;
- inode->i_fop = &squashfs_dir_ops;
- inode->i_mode |= S_IFDIR;
- squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
- squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset);
- squashfs_i(inode)->dir_idx_start = block;
- squashfs_i(inode)->dir_idx_offset = offset;
- squashfs_i(inode)->dir_idx_cnt = le16_to_cpu(sqsh_ino->i_count);
- squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode);
-
- TRACE("Long directory inode %x:%x, start_block %llx, offset "
- "%x\n", SQUASHFS_INODE_BLK(ino), offset,
- squashfs_i(inode)->start,
- le16_to_cpu(sqsh_ino->offset));
- break;
- }
- case SQUASHFS_SYMLINK_TYPE:
- case SQUASHFS_LSYMLINK_TYPE: {
- struct squashfs_symlink_inode *sqsh_ino = &squashfs_ino.symlink;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- inode->i_size = le32_to_cpu(sqsh_ino->symlink_size);
- inode->i_op = &squashfs_symlink_inode_ops;
- inode->i_data.a_ops = &squashfs_symlink_aops;
- inode->i_mode |= S_IFLNK;
- squashfs_i(inode)->start = block;
- squashfs_i(inode)->offset = offset;
-
- if (type == SQUASHFS_LSYMLINK_TYPE) {
- __le32 xattr;
-
- err = squashfs_read_metadata(sb, NULL, &block,
- &offset, inode->i_size);
- if (err < 0)
- goto failed_read;
- err = squashfs_read_metadata(sb, &xattr, &block,
- &offset, sizeof(xattr));
- if (err < 0)
- goto failed_read;
- xattr_id = le32_to_cpu(xattr);
- }
-
- TRACE("Symbolic link inode %x:%x, start_block %llx, offset "
- "%x\n", SQUASHFS_INODE_BLK(ino), offset,
- block, offset);
- break;
- }
- case SQUASHFS_BLKDEV_TYPE:
- case SQUASHFS_CHRDEV_TYPE: {
- struct squashfs_dev_inode *sqsh_ino = &squashfs_ino.dev;
- unsigned int rdev;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- if (type == SQUASHFS_CHRDEV_TYPE)
- inode->i_mode |= S_IFCHR;
- else
- inode->i_mode |= S_IFBLK;
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- rdev = le32_to_cpu(sqsh_ino->rdev);
- init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
-
- TRACE("Device inode %x:%x, rdev %x\n",
- SQUASHFS_INODE_BLK(ino), offset, rdev);
- break;
- }
- case SQUASHFS_LBLKDEV_TYPE:
- case SQUASHFS_LCHRDEV_TYPE: {
- struct squashfs_ldev_inode *sqsh_ino = &squashfs_ino.ldev;
- unsigned int rdev;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- if (type == SQUASHFS_LCHRDEV_TYPE)
- inode->i_mode |= S_IFCHR;
- else
- inode->i_mode |= S_IFBLK;
- xattr_id = le32_to_cpu(sqsh_ino->xattr);
- inode->i_op = &squashfs_inode_ops;
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- rdev = le32_to_cpu(sqsh_ino->rdev);
- init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
-
- TRACE("Device inode %x:%x, rdev %x\n",
- SQUASHFS_INODE_BLK(ino), offset, rdev);
- break;
- }
- case SQUASHFS_FIFO_TYPE:
- case SQUASHFS_SOCKET_TYPE: {
- struct squashfs_ipc_inode *sqsh_ino = &squashfs_ino.ipc;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- if (type == SQUASHFS_FIFO_TYPE)
- inode->i_mode |= S_IFIFO;
- else
- inode->i_mode |= S_IFSOCK;
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- init_special_inode(inode, inode->i_mode, 0);
- break;
- }
- case SQUASHFS_LFIFO_TYPE:
- case SQUASHFS_LSOCKET_TYPE: {
- struct squashfs_lipc_inode *sqsh_ino = &squashfs_ino.lipc;
-
- err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
- sizeof(*sqsh_ino));
- if (err < 0)
- goto failed_read;
-
- if (type == SQUASHFS_LFIFO_TYPE)
- inode->i_mode |= S_IFIFO;
- else
- inode->i_mode |= S_IFSOCK;
- xattr_id = le32_to_cpu(sqsh_ino->xattr);
- inode->i_op = &squashfs_inode_ops;
- set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
- init_special_inode(inode, inode->i_mode, 0);
- break;
- }
- default:
- ERROR("Unknown inode type %d in squashfs_iget!\n", type);
- return -EINVAL;
- }
-
- if (xattr_id != SQUASHFS_INVALID_XATTR && msblk->xattr_id_table) {
- err = squashfs_xattr_lookup(sb, xattr_id,
- &squashfs_i(inode)->xattr_count,
- &squashfs_i(inode)->xattr_size,
- &squashfs_i(inode)->xattr);
- if (err < 0)
- goto failed_read;
- inode->i_blocks += ((squashfs_i(inode)->xattr_size - 1) >> 9)
- + 1;
- } else
- squashfs_i(inode)->xattr_count = 0;
-
- return 0;
-
-failed_read:
- ERROR("Unable to read inode 0x%llx\n", ino);
- return err;
-}
-
-
-const struct inode_operations squashfs_inode_ops = {
- .getxattr = generic_getxattr,
- .listxattr = squashfs_listxattr
-};
-
diff --git a/ANDROID_3.4.5/fs/squashfs/lzo_wrapper.c b/ANDROID_3.4.5/fs/squashfs/lzo_wrapper.c
deleted file mode 100644
index 00f4dfc5..00000000
--- a/ANDROID_3.4.5/fs/squashfs/lzo_wrapper.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2010 LG Electronics
- * Chan Jeong <chan.jeong@lge.com>
- *
- * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * lzo_wrapper.c
- */
-
-#include <linux/mutex.h>
-#include <linux/buffer_head.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/lzo.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-#include "decompressor.h"
-
-struct squashfs_lzo {
- void *input;
- void *output;
-};
-
-static void *lzo_init(struct squashfs_sb_info *msblk, void *buff, int len)
-{
- int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
-
- struct squashfs_lzo *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
- if (stream == NULL)
- goto failed;
- stream->input = vmalloc(block_size);
- if (stream->input == NULL)
- goto failed;
- stream->output = vmalloc(block_size);
- if (stream->output == NULL)
- goto failed2;
-
- return stream;
-
-failed2:
- vfree(stream->input);
-failed:
- ERROR("Failed to allocate lzo workspace\n");
- kfree(stream);
- return ERR_PTR(-ENOMEM);
-}
-
-
-static void lzo_free(void *strm)
-{
- struct squashfs_lzo *stream = strm;
-
- if (stream) {
- vfree(stream->input);
- vfree(stream->output);
- }
- kfree(stream);
-}
-
-
-static int lzo_uncompress(struct squashfs_sb_info *msblk, void **buffer,
- struct buffer_head **bh, int b, int offset, int length, int srclength,
- int pages)
-{
- struct squashfs_lzo *stream = msblk->stream;
- void *buff = stream->input;
- int avail, i, bytes = length, res;
- size_t out_len = srclength;
-
- mutex_lock(&msblk->read_data_mutex);
-
- for (i = 0; i < b; i++) {
- wait_on_buffer(bh[i]);
- if (!buffer_uptodate(bh[i]))
- goto block_release;
-
- avail = min(bytes, msblk->devblksize - offset);
- memcpy(buff, bh[i]->b_data + offset, avail);
- buff += avail;
- bytes -= avail;
- offset = 0;
- put_bh(bh[i]);
- }
-
- res = lzo1x_decompress_safe(stream->input, (size_t)length,
- stream->output, &out_len);
- if (res != LZO_E_OK)
- goto failed;
-
- res = bytes = (int)out_len;
- for (i = 0, buff = stream->output; bytes && i < pages; i++) {
- avail = min_t(int, bytes, PAGE_CACHE_SIZE);
- memcpy(buffer[i], buff, avail);
- buff += avail;
- bytes -= avail;
- }
-
- mutex_unlock(&msblk->read_data_mutex);
- return res;
-
-block_release:
- for (; i < b; i++)
- put_bh(bh[i]);
-
-failed:
- mutex_unlock(&msblk->read_data_mutex);
-
- ERROR("lzo decompression failed, data probably corrupt\n");
- return -EIO;
-}
-
-const struct squashfs_decompressor squashfs_lzo_comp_ops = {
- .init = lzo_init,
- .free = lzo_free,
- .decompress = lzo_uncompress,
- .id = LZO_COMPRESSION,
- .name = "lzo",
- .supported = 1
-};
diff --git a/ANDROID_3.4.5/fs/squashfs/namei.c b/ANDROID_3.4.5/fs/squashfs/namei.c
deleted file mode 100644
index abcc58f3..00000000
--- a/ANDROID_3.4.5/fs/squashfs/namei.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * namei.c
- */
-
-/*
- * This file implements code to do filename lookup in directories.
- *
- * Like inodes, directories are packed into compressed metadata blocks, stored
- * in a directory table. Directories are accessed using the start address of
- * the metablock containing the directory and the offset into the
- * decompressed block (<block, offset>).
- *
- * Directories are organised in a slightly complex way, and are not simply
- * a list of file names. The organisation takes advantage of the
- * fact that (in most cases) the inodes of the files will be in the same
- * compressed metadata block, and therefore, can share the start block.
- * Directories are therefore organised in a two level list, a directory
- * header containing the shared start block value, and a sequence of directory
- * entries, each of which share the shared start block. A new directory header
- * is written once/if the inode start block changes. The directory
- * header/directory entry list is repeated as many times as necessary.
- *
- * Directories are sorted, and can contain a directory index to speed up
- * file lookup. Directory indexes store one entry per metablock, each entry
- * storing the index/filename mapping to the first directory header
- * in each metadata block. Directories are sorted in alphabetical order,
- * and at lookup the index is scanned linearly looking for the first filename
- * alphabetically larger than the filename being looked up. At this point the
- * location of the metadata block the filename is in has been found.
- * The general idea of the index is ensure only one metadata block needs to be
- * decompressed to do a lookup irrespective of the length of the directory.
- * This scheme has the advantage that it doesn't require extra memory overhead
- * and doesn't require much extra storage on disk.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/dcache.h>
-#include <linux/xattr.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-#include "xattr.h"
-
-/*
- * Lookup name in the directory index, returning the location of the metadata
- * block containing it, and the directory index this represents.
- *
- * If we get an error reading the index then return the part of the index
- * (if any) we have managed to read - the index isn't essential, just
- * quicker.
- */
-static int get_dir_index_using_name(struct super_block *sb,
- u64 *next_block, int *next_offset, u64 index_start,
- int index_offset, int i_count, const char *name,
- int len)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int i, size, length = 0, err;
- struct squashfs_dir_index *index;
- char *str;
-
- TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
-
- index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN * 2 + 2, GFP_KERNEL);
- if (index == NULL) {
- ERROR("Failed to allocate squashfs_dir_index\n");
- goto out;
- }
-
- str = &index->name[SQUASHFS_NAME_LEN + 1];
- strncpy(str, name, len);
- str[len] = '\0';
-
- for (i = 0; i < i_count; i++) {
- err = squashfs_read_metadata(sb, index, &index_start,
- &index_offset, sizeof(*index));
- if (err < 0)
- break;
-
-
- size = le32_to_cpu(index->size) + 1;
-
- err = squashfs_read_metadata(sb, index->name, &index_start,
- &index_offset, size);
- if (err < 0)
- break;
-
- index->name[size] = '\0';
-
- if (strcmp(index->name, str) > 0)
- break;
-
- length = le32_to_cpu(index->index);
- *next_block = le32_to_cpu(index->start_block) +
- msblk->directory_table;
- }
-
- *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
- kfree(index);
-
-out:
- /*
- * Return index (f_pos) of the looked up metadata block. Translate
- * from internal f_pos to external f_pos which is offset by 3 because
- * we invent "." and ".." entries which are not actually stored in the
- * directory.
- */
- return length + 3;
-}
-
-
-static struct dentry *squashfs_lookup(struct inode *dir, 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 = dir->i_sb->s_fs_info;
- struct squashfs_dir_header dirh;
- struct squashfs_dir_entry *dire;
- u64 block = squashfs_i(dir)->start + msblk->directory_table;
- int offset = squashfs_i(dir)->offset;
- int err, length, dir_count, size;
-
- TRACE("Entered squashfs_lookup [%llx:%x]\n", block, offset);
-
- dire = kmalloc(sizeof(*dire) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
- if (dire == NULL) {
- ERROR("Failed to allocate squashfs_dir_entry\n");
- return ERR_PTR(-ENOMEM);
- }
-
- if (len > SQUASHFS_NAME_LEN) {
- err = -ENAMETOOLONG;
- goto failed;
- }
-
- length = get_dir_index_using_name(dir->i_sb, &block, &offset,
- squashfs_i(dir)->dir_idx_start,
- squashfs_i(dir)->dir_idx_offset,
- squashfs_i(dir)->dir_idx_cnt, name, len);
-
- while (length < i_size_read(dir)) {
- /*
- * Read directory header.
- */
- err = squashfs_read_metadata(dir->i_sb, &dirh, &block,
- &offset, sizeof(dirh));
- if (err < 0)
- goto read_failure;
-
- length += sizeof(dirh);
-
- dir_count = le32_to_cpu(dirh.count) + 1;
-
- if (dir_count > SQUASHFS_DIR_COUNT)
- goto data_error;
-
- while (dir_count--) {
- /*
- * Read directory entry.
- */
- err = squashfs_read_metadata(dir->i_sb, dire, &block,
- &offset, sizeof(*dire));
- if (err < 0)
- goto read_failure;
-
- size = le16_to_cpu(dire->size) + 1;
-
- /* size should never be larger than SQUASHFS_NAME_LEN */
- if (size > SQUASHFS_NAME_LEN)
- goto data_error;
-
- err = squashfs_read_metadata(dir->i_sb, dire->name,
- &block, &offset, size);
- if (err < 0)
- goto read_failure;
-
- length += sizeof(*dire) + size;
-
- if (name[0] < dire->name[0])
- goto exit_lookup;
-
- if (len == size && !strncmp(name, dire->name, len)) {
- unsigned int blk, off, ino_num;
- long long ino;
- blk = le32_to_cpu(dirh.start_block);
- off = le16_to_cpu(dire->offset);
- ino_num = le32_to_cpu(dirh.inode_number) +
- (short) le16_to_cpu(dire->inode_number);
- ino = SQUASHFS_MKINODE(blk, off);
-
- TRACE("calling squashfs_iget for directory "
- "entry %s, inode %x:%x, %d\n", name,
- blk, off, ino_num);
-
- inode = squashfs_iget(dir->i_sb, ino, ino_num);
- goto exit_lookup;
- }
- }
- }
-
-exit_lookup:
- kfree(dire);
- return d_splice_alias(inode, dentry);
-
-data_error:
- err = -EIO;
-
-read_failure:
- ERROR("Unable to read directory block [%llx:%x]\n",
- squashfs_i(dir)->start + msblk->directory_table,
- squashfs_i(dir)->offset);
-failed:
- kfree(dire);
- return ERR_PTR(err);
-}
-
-
-const struct inode_operations squashfs_dir_inode_ops = {
- .lookup = squashfs_lookup,
- .getxattr = generic_getxattr,
- .listxattr = squashfs_listxattr
-};
diff --git a/ANDROID_3.4.5/fs/squashfs/squashfs.h b/ANDROID_3.4.5/fs/squashfs/squashfs.h
deleted file mode 100644
index d1266516..00000000
--- a/ANDROID_3.4.5/fs/squashfs/squashfs.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * squashfs.h
- */
-
-#define TRACE(s, args...) pr_debug("SQUASHFS: "s, ## args)
-
-#define ERROR(s, args...) pr_err("SQUASHFS error: "s, ## args)
-
-#define WARNING(s, args...) pr_warning("SQUASHFS: "s, ## args)
-
-/* block.c */
-extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *,
- int, int);
-
-/* cache.c */
-extern struct squashfs_cache *squashfs_cache_init(char *, int, int);
-extern void squashfs_cache_delete(struct squashfs_cache *);
-extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *,
- struct squashfs_cache *, u64, int);
-extern void squashfs_cache_put(struct squashfs_cache_entry *);
-extern int squashfs_copy_data(void *, struct squashfs_cache_entry *, int, int);
-extern int squashfs_read_metadata(struct super_block *, void *, u64 *,
- int *, int);
-extern struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *,
- u64, int);
-extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *,
- u64, int);
-extern void *squashfs_read_table(struct super_block *, u64, int);
-
-/* decompressor.c */
-extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
-extern void *squashfs_decompressor_init(struct super_block *, unsigned short);
-
-/* export.c */
-extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, u64,
- unsigned int);
-
-/* fragment.c */
-extern int squashfs_frag_lookup(struct super_block *, unsigned int, u64 *);
-extern __le64 *squashfs_read_fragment_index_table(struct super_block *,
- u64, u64, unsigned int);
-
-/* id.c */
-extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *);
-extern __le64 *squashfs_read_id_index_table(struct super_block *, u64, u64,
- unsigned short);
-
-/* inode.c */
-extern struct inode *squashfs_iget(struct super_block *, long long,
- unsigned int);
-extern int squashfs_read_inode(struct inode *, long long);
-
-/* xattr.c */
-extern ssize_t squashfs_listxattr(struct dentry *, char *, size_t);
-
-/*
- * Inodes, files, decompressor and xattr operations
- */
-
-/* dir.c */
-extern const struct file_operations squashfs_dir_ops;
-
-/* export.c */
-extern const struct export_operations squashfs_export_ops;
-
-/* file.c */
-extern const struct address_space_operations squashfs_aops;
-
-/* inode.c */
-extern const struct inode_operations squashfs_inode_ops;
-
-/* namei.c */
-extern const struct inode_operations squashfs_dir_inode_ops;
-
-/* symlink.c */
-extern const struct address_space_operations squashfs_symlink_aops;
-extern const struct inode_operations squashfs_symlink_inode_ops;
-
-/* xattr.c */
-extern const struct xattr_handler *squashfs_xattr_handlers[];
diff --git a/ANDROID_3.4.5/fs/squashfs/squashfs_fs.h b/ANDROID_3.4.5/fs/squashfs/squashfs_fs.h
deleted file mode 100644
index 9e2349d0..00000000
--- a/ANDROID_3.4.5/fs/squashfs/squashfs_fs.h
+++ /dev/null
@@ -1,453 +0,0 @@
-#ifndef SQUASHFS_FS
-#define SQUASHFS_FS
-/*
- * Squashfs
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * squashfs_fs.h
- */
-
-#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
-#define SQUASHFS_MAJOR 4
-#define SQUASHFS_MINOR 0
-#define SQUASHFS_START 0
-
-/* size of metadata (inode and directory) blocks */
-#define SQUASHFS_METADATA_SIZE 8192
-
-/* default size of block device I/O */
-#ifdef CONFIG_SQUASHFS_4K_DEVBLK_SIZE
-#define SQUASHFS_DEVBLK_SIZE 4096
-#else
-#define SQUASHFS_DEVBLK_SIZE 1024
-#endif
-
-#define SQUASHFS_FILE_MAX_SIZE 1048576
-#define SQUASHFS_FILE_MAX_LOG 20
-
-/* Max length of filename (not 255) */
-#define SQUASHFS_NAME_LEN 256
-
-/* Max value for directory header count*/
-#define SQUASHFS_DIR_COUNT 256
-
-#define SQUASHFS_INVALID_FRAG (0xffffffffU)
-#define SQUASHFS_INVALID_XATTR (0xffffffffU)
-#define SQUASHFS_INVALID_BLK (-1LL)
-
-/* Filesystem flags */
-#define SQUASHFS_NOI 0
-#define SQUASHFS_NOD 1
-#define SQUASHFS_NOF 3
-#define SQUASHFS_NO_FRAG 4
-#define SQUASHFS_ALWAYS_FRAG 5
-#define SQUASHFS_DUPLICATE 6
-#define SQUASHFS_EXPORT 7
-#define SQUASHFS_COMP_OPT 10
-
-#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
-
-#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_NOI)
-
-#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_NOD)
-
-#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_NOF)
-
-#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_NO_FRAG)
-
-#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_ALWAYS_FRAG)
-
-#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_DUPLICATE)
-
-#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_EXPORT)
-
-#define SQUASHFS_COMP_OPTS(flags) SQUASHFS_BIT(flags, \
- SQUASHFS_COMP_OPT)
-
-/* Max number of types and file types */
-#define SQUASHFS_DIR_TYPE 1
-#define SQUASHFS_REG_TYPE 2
-#define SQUASHFS_SYMLINK_TYPE 3
-#define SQUASHFS_BLKDEV_TYPE 4
-#define SQUASHFS_CHRDEV_TYPE 5
-#define SQUASHFS_FIFO_TYPE 6
-#define SQUASHFS_SOCKET_TYPE 7
-#define SQUASHFS_LDIR_TYPE 8
-#define SQUASHFS_LREG_TYPE 9
-#define SQUASHFS_LSYMLINK_TYPE 10
-#define SQUASHFS_LBLKDEV_TYPE 11
-#define SQUASHFS_LCHRDEV_TYPE 12
-#define SQUASHFS_LFIFO_TYPE 13
-#define SQUASHFS_LSOCKET_TYPE 14
-
-/* Xattr types */
-#define SQUASHFS_XATTR_USER 0
-#define SQUASHFS_XATTR_TRUSTED 1
-#define SQUASHFS_XATTR_SECURITY 2
-#define SQUASHFS_XATTR_VALUE_OOL 256
-#define SQUASHFS_XATTR_PREFIX_MASK 0xff
-
-/* Flag whether block is compressed or uncompressed, bit is set if block is
- * uncompressed */
-#define SQUASHFS_COMPRESSED_BIT (1 << 15)
-
-#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
- (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
-
-#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
-
-#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
-
-#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \
- ~SQUASHFS_COMPRESSED_BIT_BLOCK)
-
-#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
-
-/*
- * Inode number ops. Inodes consist of a compressed block number, and an
- * uncompressed offset within that block
- */
-#define SQUASHFS_INODE_BLK(A) ((unsigned int) ((A) >> 16))
-
-#define SQUASHFS_INODE_OFFSET(A) ((unsigned int) ((A) & 0xffff))
-
-#define SQUASHFS_MKINODE(A, B) ((long long)(((long long) (A)\
- << 16) + (B)))
-
-/* fragment and fragment table defines */
-#define SQUASHFS_FRAGMENT_BYTES(A) \
- ((A) * sizeof(struct squashfs_fragment_entry))
-
-#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
- SQUASHFS_METADATA_SIZE - 1) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
- sizeof(u64))
-
-/* inode lookup table defines */
-#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(u64))
-
-#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
- SQUASHFS_METADATA_SIZE - 1) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
- sizeof(u64))
-
-/* uid/gid lookup table defines */
-#define SQUASHFS_ID_BYTES(A) ((A) * sizeof(unsigned int))
-
-#define SQUASHFS_ID_BLOCK(A) (SQUASHFS_ID_BYTES(A) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_ID_BLOCK_OFFSET(A) (SQUASHFS_ID_BYTES(A) % \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_ID_BLOCKS(A) ((SQUASHFS_ID_BYTES(A) + \
- SQUASHFS_METADATA_SIZE - 1) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\
- sizeof(u64))
-/* xattr id lookup table defines */
-#define SQUASHFS_XATTR_BYTES(A) ((A) * sizeof(struct squashfs_xattr_id))
-
-#define SQUASHFS_XATTR_BLOCK(A) (SQUASHFS_XATTR_BYTES(A) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_XATTR_BLOCK_OFFSET(A) (SQUASHFS_XATTR_BYTES(A) % \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_XATTR_BLOCKS(A) ((SQUASHFS_XATTR_BYTES(A) + \
- SQUASHFS_METADATA_SIZE - 1) / \
- SQUASHFS_METADATA_SIZE)
-
-#define SQUASHFS_XATTR_BLOCK_BYTES(A) (SQUASHFS_XATTR_BLOCKS(A) *\
- sizeof(u64))
-#define SQUASHFS_XATTR_BLK(A) ((unsigned int) ((A) >> 16))
-
-#define SQUASHFS_XATTR_OFFSET(A) ((unsigned int) ((A) & 0xffff))
-
-/* cached data constants for filesystem */
-#define SQUASHFS_CACHED_BLKS 8
-
-/* meta index cache */
-#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
-#define SQUASHFS_META_ENTRIES 127
-#define SQUASHFS_META_SLOTS 8
-
-struct meta_entry {
- u64 data_block;
- unsigned int index_block;
- unsigned short offset;
- unsigned short pad;
-};
-
-struct meta_index {
- unsigned int inode_number;
- unsigned int offset;
- unsigned short entries;
- unsigned short skip;
- unsigned short locked;
- unsigned short pad;
- struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
-};
-
-
-/*
- * definitions for structures on disk
- */
-#define ZLIB_COMPRESSION 1
-#define LZMA_COMPRESSION 2
-#define LZO_COMPRESSION 3
-#define XZ_COMPRESSION 4
-
-struct squashfs_super_block {
- __le32 s_magic;
- __le32 inodes;
- __le32 mkfs_time;
- __le32 block_size;
- __le32 fragments;
- __le16 compression;
- __le16 block_log;
- __le16 flags;
- __le16 no_ids;
- __le16 s_major;
- __le16 s_minor;
- __le64 root_inode;
- __le64 bytes_used;
- __le64 id_table_start;
- __le64 xattr_id_table_start;
- __le64 inode_table_start;
- __le64 directory_table_start;
- __le64 fragment_table_start;
- __le64 lookup_table_start;
-};
-
-struct squashfs_dir_index {
- __le32 index;
- __le32 start_block;
- __le32 size;
- unsigned char name[0];
-};
-
-struct squashfs_base_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
-};
-
-struct squashfs_ipc_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 nlink;
-};
-
-struct squashfs_lipc_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 nlink;
- __le32 xattr;
-};
-
-struct squashfs_dev_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 nlink;
- __le32 rdev;
-};
-
-struct squashfs_ldev_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 nlink;
- __le32 rdev;
- __le32 xattr;
-};
-
-struct squashfs_symlink_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 nlink;
- __le32 symlink_size;
- char symlink[0];
-};
-
-struct squashfs_reg_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 start_block;
- __le32 fragment;
- __le32 offset;
- __le32 file_size;
- __le16 block_list[0];
-};
-
-struct squashfs_lreg_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le64 start_block;
- __le64 file_size;
- __le64 sparse;
- __le32 nlink;
- __le32 fragment;
- __le32 offset;
- __le32 xattr;
- __le16 block_list[0];
-};
-
-struct squashfs_dir_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 start_block;
- __le32 nlink;
- __le16 file_size;
- __le16 offset;
- __le32 parent_inode;
-};
-
-struct squashfs_ldir_inode {
- __le16 inode_type;
- __le16 mode;
- __le16 uid;
- __le16 guid;
- __le32 mtime;
- __le32 inode_number;
- __le32 nlink;
- __le32 file_size;
- __le32 start_block;
- __le32 parent_inode;
- __le16 i_count;
- __le16 offset;
- __le32 xattr;
- struct squashfs_dir_index index[0];
-};
-
-union squashfs_inode {
- struct squashfs_base_inode base;
- struct squashfs_dev_inode dev;
- struct squashfs_ldev_inode ldev;
- struct squashfs_symlink_inode symlink;
- struct squashfs_reg_inode reg;
- struct squashfs_lreg_inode lreg;
- struct squashfs_dir_inode dir;
- struct squashfs_ldir_inode ldir;
- struct squashfs_ipc_inode ipc;
- struct squashfs_lipc_inode lipc;
-};
-
-struct squashfs_dir_entry {
- __le16 offset;
- __le16 inode_number;
- __le16 type;
- __le16 size;
- char name[0];
-};
-
-struct squashfs_dir_header {
- __le32 count;
- __le32 start_block;
- __le32 inode_number;
-};
-
-struct squashfs_fragment_entry {
- __le64 start_block;
- __le32 size;
- unsigned int unused;
-};
-
-struct squashfs_xattr_entry {
- __le16 type;
- __le16 size;
- char data[0];
-};
-
-struct squashfs_xattr_val {
- __le32 vsize;
- char value[0];
-};
-
-struct squashfs_xattr_id {
- __le64 xattr;
- __le32 count;
- __le32 size;
-};
-
-struct squashfs_xattr_id_table {
- __le64 xattr_table_start;
- __le32 xattr_ids;
- __le32 unused;
-};
-
-#endif
diff --git a/ANDROID_3.4.5/fs/squashfs/squashfs_fs_i.h b/ANDROID_3.4.5/fs/squashfs/squashfs_fs_i.h
deleted file mode 100644
index 73588e77..00000000
--- a/ANDROID_3.4.5/fs/squashfs/squashfs_fs_i.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef SQUASHFS_FS_I
-#define SQUASHFS_FS_I
-/*
- * Squashfs
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * squashfs_fs_i.h
- */
-
-struct squashfs_inode_info {
- u64 start;
- int offset;
- u64 xattr;
- unsigned int xattr_size;
- int xattr_count;
- union {
- struct {
- u64 fragment_block;
- int fragment_size;
- int fragment_offset;
- u64 block_list_start;
- };
- struct {
- u64 dir_idx_start;
- int dir_idx_offset;
- int dir_idx_cnt;
- int parent;
- };
- };
- struct inode vfs_inode;
-};
-
-
-static inline struct squashfs_inode_info *squashfs_i(struct inode *inode)
-{
- return list_entry(inode, struct squashfs_inode_info, vfs_inode);
-}
-#endif
diff --git a/ANDROID_3.4.5/fs/squashfs/squashfs_fs_sb.h b/ANDROID_3.4.5/fs/squashfs/squashfs_fs_sb.h
deleted file mode 100644
index 52934a22..00000000
--- a/ANDROID_3.4.5/fs/squashfs/squashfs_fs_sb.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef SQUASHFS_FS_SB
-#define SQUASHFS_FS_SB
-/*
- * Squashfs
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * squashfs_fs_sb.h
- */
-
-#include "squashfs_fs.h"
-
-struct squashfs_cache {
- char *name;
- int entries;
- int curr_blk;
- int next_blk;
- int num_waiters;
- int unused;
- int block_size;
- int pages;
- spinlock_t lock;
- wait_queue_head_t wait_queue;
- struct squashfs_cache_entry *entry;
-};
-
-struct squashfs_cache_entry {
- u64 block;
- int length;
- int refcount;
- u64 next_index;
- int pending;
- int error;
- int num_waiters;
- wait_queue_head_t wait_queue;
- struct squashfs_cache *cache;
- void **data;
-};
-
-struct squashfs_sb_info {
- const struct squashfs_decompressor *decompressor;
- int devblksize;
- int devblksize_log2;
- struct squashfs_cache *block_cache;
- struct squashfs_cache *fragment_cache;
- struct squashfs_cache *read_page;
- int next_meta_index;
- __le64 *id_table;
- __le64 *fragment_index;
- __le64 *xattr_id_table;
- struct mutex read_data_mutex;
- struct mutex meta_index_mutex;
- struct meta_index *meta_index;
- void *stream;
- __le64 *inode_lookup_table;
- u64 inode_table;
- u64 directory_table;
- u64 xattr_table;
- unsigned int block_size;
- unsigned short block_log;
- long long bytes_used;
- unsigned int inodes;
- int xattr_ids;
-};
-#endif
diff --git a/ANDROID_3.4.5/fs/squashfs/super.c b/ANDROID_3.4.5/fs/squashfs/super.c
deleted file mode 100644
index 29cd014e..00000000
--- a/ANDROID_3.4.5/fs/squashfs/super.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * super.c
- */
-
-/*
- * This file implements code to read the superblock, read and initialise
- * in-memory structures at mount time, and all the VFS glue code to register
- * the filesystem.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/pagemap.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/magic.h>
-#include <linux/xattr.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-#include "decompressor.h"
-#include "xattr.h"
-
-static struct file_system_type squashfs_fs_type;
-static const struct super_operations squashfs_super_ops;
-
-static const struct squashfs_decompressor *supported_squashfs_filesystem(short
- major, short minor, short id)
-{
- const struct squashfs_decompressor *decompressor;
-
- if (major < SQUASHFS_MAJOR) {
- ERROR("Major/Minor mismatch, older Squashfs %d.%d "
- "filesystems are unsupported\n", major, minor);
- return NULL;
- } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
- ERROR("Major/Minor mismatch, trying to mount newer "
- "%d.%d filesystem\n", major, minor);
- ERROR("Please update your kernel\n");
- return NULL;
- }
-
- decompressor = squashfs_lookup_decompressor(id);
- if (!decompressor->supported) {
- ERROR("Filesystem uses \"%s\" compression. This is not "
- "supported\n", decompressor->name);
- return NULL;
- }
-
- return decompressor;
-}
-
-
-static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
-{
- struct squashfs_sb_info *msblk;
- struct squashfs_super_block *sblk = NULL;
- char b[BDEVNAME_SIZE];
- struct inode *root;
- long long root_inode;
- unsigned short flags;
- unsigned int fragments;
- u64 lookup_table_start, xattr_id_table_start, next_table;
- int err;
-
- TRACE("Entered squashfs_fill_superblock\n");
-
- sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
- if (sb->s_fs_info == NULL) {
- ERROR("Failed to allocate squashfs_sb_info\n");
- return -ENOMEM;
- }
- msblk = sb->s_fs_info;
-
- msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
- msblk->devblksize_log2 = ffz(~msblk->devblksize);
-
- mutex_init(&msblk->read_data_mutex);
- mutex_init(&msblk->meta_index_mutex);
-
- /*
- * msblk->bytes_used is checked in squashfs_read_table to ensure reads
- * are not beyond filesystem end. But as we're using
- * squashfs_read_table here to read the superblock (including the value
- * of bytes_used) we need to set it to an initial sensible dummy value
- */
- msblk->bytes_used = sizeof(*sblk);
- sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
-
- if (IS_ERR(sblk)) {
- ERROR("unable to read squashfs_super_block\n");
- err = PTR_ERR(sblk);
- sblk = NULL;
- goto failed_mount;
- }
-
- err = -EINVAL;
-
- /* Check it is a SQUASHFS superblock */
- sb->s_magic = le32_to_cpu(sblk->s_magic);
- if (sb->s_magic != SQUASHFS_MAGIC) {
- if (!silent)
- ERROR("Can't find a SQUASHFS superblock on %s\n",
- bdevname(sb->s_bdev, b));
- goto failed_mount;
- }
-
- /* Check the MAJOR & MINOR versions and lookup compression type */
- msblk->decompressor = supported_squashfs_filesystem(
- le16_to_cpu(sblk->s_major),
- le16_to_cpu(sblk->s_minor),
- le16_to_cpu(sblk->compression));
- if (msblk->decompressor == NULL)
- goto failed_mount;
-
- /* Check the filesystem does not extend beyond the end of the
- block device */
- msblk->bytes_used = le64_to_cpu(sblk->bytes_used);
- if (msblk->bytes_used < 0 || msblk->bytes_used >
- i_size_read(sb->s_bdev->bd_inode))
- goto failed_mount;
-
- /* Check block size for sanity */
- msblk->block_size = le32_to_cpu(sblk->block_size);
- if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
- goto failed_mount;
-
- /*
- * Check the system page size is not larger than the filesystem
- * block size (by default 128K). This is currently not supported.
- */
- if (PAGE_CACHE_SIZE > msblk->block_size) {
- ERROR("Page size > filesystem block size (%d). This is "
- "currently not supported!\n", msblk->block_size);
- goto failed_mount;
- }
-
- /* Check block log for sanity */
- msblk->block_log = le16_to_cpu(sblk->block_log);
- if (msblk->block_log > SQUASHFS_FILE_MAX_LOG)
- goto failed_mount;
-
- /* Check that block_size and block_log match */
- if (msblk->block_size != (1 << msblk->block_log))
- goto failed_mount;
-
- /* Check the root inode for sanity */
- root_inode = le64_to_cpu(sblk->root_inode);
- if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
- goto failed_mount;
-
- msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
- msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
- msblk->inodes = le32_to_cpu(sblk->inodes);
- flags = le16_to_cpu(sblk->flags);
-
- TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
- TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
- ? "un" : "");
- TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
- ? "un" : "");
- TRACE("Filesystem size %lld bytes\n", msblk->bytes_used);
- TRACE("Block size %d\n", msblk->block_size);
- TRACE("Number of inodes %d\n", msblk->inodes);
- TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments));
- TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids));
- TRACE("sblk->inode_table_start %llx\n", msblk->inode_table);
- TRACE("sblk->directory_table_start %llx\n", msblk->directory_table);
- TRACE("sblk->fragment_table_start %llx\n",
- (u64) le64_to_cpu(sblk->fragment_table_start));
- TRACE("sblk->id_table_start %llx\n",
- (u64) le64_to_cpu(sblk->id_table_start));
-
- sb->s_maxbytes = MAX_LFS_FILESIZE;
- sb->s_flags |= MS_RDONLY;
- sb->s_op = &squashfs_super_ops;
-
- err = -ENOMEM;
-
- msblk->block_cache = squashfs_cache_init("metadata",
- SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
- if (msblk->block_cache == NULL)
- goto failed_mount;
-
- /* Allocate read_page block */
- msblk->read_page = squashfs_cache_init("data", 1, msblk->block_size);
- if (msblk->read_page == NULL) {
- ERROR("Failed to allocate read_page block\n");
- goto failed_mount;
- }
-
- msblk->stream = squashfs_decompressor_init(sb, flags);
- if (IS_ERR(msblk->stream)) {
- err = PTR_ERR(msblk->stream);
- msblk->stream = NULL;
- goto failed_mount;
- }
-
- /* Handle xattrs */
- sb->s_xattr = squashfs_xattr_handlers;
- xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
- if (xattr_id_table_start == SQUASHFS_INVALID_BLK) {
- next_table = msblk->bytes_used;
- goto allocate_id_index_table;
- }
-
- /* Allocate and read xattr id lookup table */
- msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
- xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
- if (IS_ERR(msblk->xattr_id_table)) {
- ERROR("unable to read xattr id index table\n");
- err = PTR_ERR(msblk->xattr_id_table);
- msblk->xattr_id_table = NULL;
- if (err != -ENOTSUPP)
- goto failed_mount;
- }
- next_table = msblk->xattr_table;
-
-allocate_id_index_table:
- /* Allocate and read id index table */
- msblk->id_table = squashfs_read_id_index_table(sb,
- le64_to_cpu(sblk->id_table_start), next_table,
- le16_to_cpu(sblk->no_ids));
- if (IS_ERR(msblk->id_table)) {
- ERROR("unable to read id index table\n");
- err = PTR_ERR(msblk->id_table);
- msblk->id_table = NULL;
- goto failed_mount;
- }
- next_table = le64_to_cpu(msblk->id_table[0]);
-
- /* Handle inode lookup table */
- lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
- if (lookup_table_start == SQUASHFS_INVALID_BLK)
- goto handle_fragments;
-
- /* Allocate and read inode lookup table */
- msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
- lookup_table_start, next_table, msblk->inodes);
- if (IS_ERR(msblk->inode_lookup_table)) {
- ERROR("unable to read inode lookup table\n");
- err = PTR_ERR(msblk->inode_lookup_table);
- msblk->inode_lookup_table = NULL;
- goto failed_mount;
- }
- next_table = le64_to_cpu(msblk->inode_lookup_table[0]);
-
- sb->s_export_op = &squashfs_export_ops;
-
-handle_fragments:
- fragments = le32_to_cpu(sblk->fragments);
- if (fragments == 0)
- goto check_directory_table;
-
- msblk->fragment_cache = squashfs_cache_init("fragment",
- SQUASHFS_CACHED_FRAGMENTS, msblk->block_size);
- if (msblk->fragment_cache == NULL) {
- err = -ENOMEM;
- goto failed_mount;
- }
-
- /* Allocate and read fragment index table */
- msblk->fragment_index = squashfs_read_fragment_index_table(sb,
- le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
- if (IS_ERR(msblk->fragment_index)) {
- ERROR("unable to read fragment index table\n");
- err = PTR_ERR(msblk->fragment_index);
- msblk->fragment_index = NULL;
- goto failed_mount;
- }
- next_table = le64_to_cpu(msblk->fragment_index[0]);
-
-check_directory_table:
- /* Sanity check directory_table */
- if (msblk->directory_table > next_table) {
- err = -EINVAL;
- goto failed_mount;
- }
-
- /* Sanity check inode_table */
- if (msblk->inode_table >= msblk->directory_table) {
- err = -EINVAL;
- goto failed_mount;
- }
-
- /* allocate root */
- root = new_inode(sb);
- if (!root) {
- err = -ENOMEM;
- goto failed_mount;
- }
-
- err = squashfs_read_inode(root, root_inode);
- if (err) {
- make_bad_inode(root);
- iput(root);
- goto failed_mount;
- }
- insert_inode_hash(root);
-
- sb->s_root = d_make_root(root);
- if (sb->s_root == NULL) {
- ERROR("Root inode create failed\n");
- err = -ENOMEM;
- goto failed_mount;
- }
-
- TRACE("Leaving squashfs_fill_super\n");
- kfree(sblk);
- return 0;
-
-failed_mount:
- squashfs_cache_delete(msblk->block_cache);
- squashfs_cache_delete(msblk->fragment_cache);
- squashfs_cache_delete(msblk->read_page);
- squashfs_decompressor_free(msblk, msblk->stream);
- kfree(msblk->inode_lookup_table);
- kfree(msblk->fragment_index);
- kfree(msblk->id_table);
- kfree(msblk->xattr_id_table);
- kfree(sb->s_fs_info);
- sb->s_fs_info = NULL;
- kfree(sblk);
- return err;
-}
-
-
-static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
- struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
- u64 id = huge_encode_dev(dentry->d_sb->s_bdev->bd_dev);
-
- TRACE("Entered squashfs_statfs\n");
-
- buf->f_type = SQUASHFS_MAGIC;
- buf->f_bsize = msblk->block_size;
- buf->f_blocks = ((msblk->bytes_used - 1) >> msblk->block_log) + 1;
- buf->f_bfree = buf->f_bavail = 0;
- buf->f_files = msblk->inodes;
- buf->f_ffree = 0;
- buf->f_namelen = SQUASHFS_NAME_LEN;
- buf->f_fsid.val[0] = (u32)id;
- buf->f_fsid.val[1] = (u32)(id >> 32);
-
- return 0;
-}
-
-
-static int squashfs_remount(struct super_block *sb, int *flags, char *data)
-{
- *flags |= MS_RDONLY;
- return 0;
-}
-
-
-static void squashfs_put_super(struct super_block *sb)
-{
- if (sb->s_fs_info) {
- struct squashfs_sb_info *sbi = sb->s_fs_info;
- squashfs_cache_delete(sbi->block_cache);
- squashfs_cache_delete(sbi->fragment_cache);
- squashfs_cache_delete(sbi->read_page);
- squashfs_decompressor_free(sbi, sbi->stream);
- kfree(sbi->id_table);
- kfree(sbi->fragment_index);
- kfree(sbi->meta_index);
- kfree(sbi->inode_lookup_table);
- kfree(sbi->xattr_id_table);
- kfree(sb->s_fs_info);
- sb->s_fs_info = NULL;
- }
-}
-
-
-static struct dentry *squashfs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
-{
- return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
-}
-
-
-static struct kmem_cache *squashfs_inode_cachep;
-
-
-static void init_once(void *foo)
-{
- struct squashfs_inode_info *ei = foo;
-
- 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);
-
- return squashfs_inode_cachep ? 0 : -ENOMEM;
-}
-
-
-static void destroy_inodecache(void)
-{
- kmem_cache_destroy(squashfs_inode_cachep);
-}
-
-
-static int __init init_squashfs_fs(void)
-{
- int err = init_inodecache();
-
- if (err)
- return err;
-
- err = register_filesystem(&squashfs_fs_type);
- if (err) {
- destroy_inodecache();
- return err;
- }
-
- printk(KERN_INFO "squashfs: version 4.0 (2009/01/31) "
- "Phillip Lougher\n");
-
- return 0;
-}
-
-
-static void __exit exit_squashfs_fs(void)
-{
- unregister_filesystem(&squashfs_fs_type);
- destroy_inodecache();
-}
-
-
-static struct inode *squashfs_alloc_inode(struct super_block *sb)
-{
- struct squashfs_inode_info *ei =
- kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
-
- return ei ? &ei->vfs_inode : NULL;
-}
-
-
-static void squashfs_i_callback(struct rcu_head *head)
-{
- struct inode *inode = container_of(head, struct inode, i_rcu);
- kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode));
-}
-
-static void squashfs_destroy_inode(struct inode *inode)
-{
- call_rcu(&inode->i_rcu, squashfs_i_callback);
-}
-
-
-static struct file_system_type squashfs_fs_type = {
- .owner = THIS_MODULE,
- .name = "squashfs",
- .mount = squashfs_mount,
- .kill_sb = kill_block_super,
- .fs_flags = FS_REQUIRES_DEV
-};
-
-static const struct super_operations squashfs_super_ops = {
- .alloc_inode = squashfs_alloc_inode,
- .destroy_inode = squashfs_destroy_inode,
- .statfs = squashfs_statfs,
- .put_super = squashfs_put_super,
- .remount_fs = squashfs_remount
-};
-
-module_init(init_squashfs_fs);
-module_exit(exit_squashfs_fs);
-MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem");
-MODULE_AUTHOR("Phillip Lougher <phillip@squashfs.org.uk>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/fs/squashfs/symlink.c b/ANDROID_3.4.5/fs/squashfs/symlink.c
deleted file mode 100644
index 12806dff..00000000
--- a/ANDROID_3.4.5/fs/squashfs/symlink.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * symlink.c
- */
-
-/*
- * This file implements code to handle symbolic links.
- *
- * The data contents of symbolic links are stored inside the symbolic
- * link inode within the inode table. This allows the normally small symbolic
- * link to be compressed as part of the inode table, achieving much greater
- * compression than if the symbolic link was compressed individually.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/pagemap.h>
-#include <linux/xattr.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-#include "xattr.h"
-
-static int squashfs_symlink_readpage(struct file *file, struct page *page)
-{
- struct inode *inode = page->mapping->host;
- struct super_block *sb = inode->i_sb;
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int index = page->index << PAGE_CACHE_SHIFT;
- u64 block = squashfs_i(inode)->start;
- int offset = squashfs_i(inode)->offset;
- int length = min_t(int, i_size_read(inode) - index, PAGE_CACHE_SIZE);
- int bytes, copied;
- void *pageaddr;
- struct squashfs_cache_entry *entry;
-
- TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
- "%llx, offset %x\n", page->index, block, offset);
-
- /*
- * Skip index bytes into symlink metadata.
- */
- if (index) {
- bytes = squashfs_read_metadata(sb, NULL, &block, &offset,
- index);
- if (bytes < 0) {
- ERROR("Unable to read symlink [%llx:%x]\n",
- squashfs_i(inode)->start,
- squashfs_i(inode)->offset);
- goto error_out;
- }
- }
-
- /*
- * Read length bytes from symlink metadata. Squashfs_read_metadata
- * is not used here because it can sleep and we want to use
- * kmap_atomic to map the page. Instead call the underlying
- * squashfs_cache_get routine. As length bytes may overlap metadata
- * blocks, we may need to call squashfs_cache_get multiple times.
- */
- for (bytes = 0; bytes < length; offset = 0, bytes += copied) {
- entry = squashfs_cache_get(sb, msblk->block_cache, block, 0);
- if (entry->error) {
- ERROR("Unable to read symlink [%llx:%x]\n",
- squashfs_i(inode)->start,
- squashfs_i(inode)->offset);
- squashfs_cache_put(entry);
- goto error_out;
- }
-
- pageaddr = kmap_atomic(page);
- copied = squashfs_copy_data(pageaddr + bytes, entry, offset,
- length - bytes);
- if (copied == length - bytes)
- memset(pageaddr + length, 0, PAGE_CACHE_SIZE - length);
- else
- block = entry->next_index;
- kunmap_atomic(pageaddr);
- squashfs_cache_put(entry);
- }
-
- flush_dcache_page(page);
- SetPageUptodate(page);
- unlock_page(page);
- return 0;
-
-error_out:
- SetPageError(page);
- unlock_page(page);
- return 0;
-}
-
-
-const struct address_space_operations squashfs_symlink_aops = {
- .readpage = squashfs_symlink_readpage
-};
-
-const struct inode_operations squashfs_symlink_inode_ops = {
- .readlink = generic_readlink,
- .follow_link = page_follow_link_light,
- .put_link = page_put_link,
- .getxattr = generic_getxattr,
- .listxattr = squashfs_listxattr
-};
-
diff --git a/ANDROID_3.4.5/fs/squashfs/xattr.c b/ANDROID_3.4.5/fs/squashfs/xattr.c
deleted file mode 100644
index 92fcde7b..00000000
--- a/ANDROID_3.4.5/fs/squashfs/xattr.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2010
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * xattr.c
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/xattr.h>
-#include <linux/slab.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs_fs_i.h"
-#include "squashfs.h"
-
-static const struct xattr_handler *squashfs_xattr_handler(int);
-
-ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
- size_t buffer_size)
-{
- struct inode *inode = d->d_inode;
- struct super_block *sb = inode->i_sb;
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- u64 start = SQUASHFS_XATTR_BLK(squashfs_i(inode)->xattr)
- + msblk->xattr_table;
- int offset = SQUASHFS_XATTR_OFFSET(squashfs_i(inode)->xattr);
- int count = squashfs_i(inode)->xattr_count;
- size_t rest = buffer_size;
- int err;
-
- /* check that the file system has xattrs */
- if (msblk->xattr_id_table == NULL)
- return -EOPNOTSUPP;
-
- /* loop reading each xattr name */
- while (count--) {
- struct squashfs_xattr_entry entry;
- struct squashfs_xattr_val val;
- const struct xattr_handler *handler;
- int name_size, prefix_size = 0;
-
- err = squashfs_read_metadata(sb, &entry, &start, &offset,
- sizeof(entry));
- if (err < 0)
- goto failed;
-
- name_size = le16_to_cpu(entry.size);
- handler = squashfs_xattr_handler(le16_to_cpu(entry.type));
- if (handler)
- prefix_size = handler->list(d, buffer, rest, NULL,
- name_size, handler->flags);
- if (prefix_size) {
- if (buffer) {
- if (prefix_size + name_size + 1 > rest) {
- err = -ERANGE;
- goto failed;
- }
- buffer += prefix_size;
- }
- err = squashfs_read_metadata(sb, buffer, &start,
- &offset, name_size);
- if (err < 0)
- goto failed;
- if (buffer) {
- buffer[name_size] = '\0';
- buffer += name_size + 1;
- }
- rest -= prefix_size + name_size + 1;
- } else {
- /* no handler or insuffficient privileges, so skip */
- err = squashfs_read_metadata(sb, NULL, &start,
- &offset, name_size);
- if (err < 0)
- goto failed;
- }
-
-
- /* skip remaining xattr entry */
- err = squashfs_read_metadata(sb, &val, &start, &offset,
- sizeof(val));
- if (err < 0)
- goto failed;
-
- err = squashfs_read_metadata(sb, NULL, &start, &offset,
- le32_to_cpu(val.vsize));
- if (err < 0)
- goto failed;
- }
- err = buffer_size - rest;
-
-failed:
- return err;
-}
-
-
-static int squashfs_xattr_get(struct inode *inode, int name_index,
- const char *name, void *buffer, size_t buffer_size)
-{
- struct super_block *sb = inode->i_sb;
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- u64 start = SQUASHFS_XATTR_BLK(squashfs_i(inode)->xattr)
- + msblk->xattr_table;
- int offset = SQUASHFS_XATTR_OFFSET(squashfs_i(inode)->xattr);
- int count = squashfs_i(inode)->xattr_count;
- int name_len = strlen(name);
- int err, vsize;
- char *target = kmalloc(name_len, GFP_KERNEL);
-
- if (target == NULL)
- return -ENOMEM;
-
- /* loop reading each xattr name */
- for (; count; count--) {
- struct squashfs_xattr_entry entry;
- struct squashfs_xattr_val val;
- int type, prefix, name_size;
-
- err = squashfs_read_metadata(sb, &entry, &start, &offset,
- sizeof(entry));
- if (err < 0)
- goto failed;
-
- name_size = le16_to_cpu(entry.size);
- type = le16_to_cpu(entry.type);
- prefix = type & SQUASHFS_XATTR_PREFIX_MASK;
-
- if (prefix == name_index && name_size == name_len)
- err = squashfs_read_metadata(sb, target, &start,
- &offset, name_size);
- else
- err = squashfs_read_metadata(sb, NULL, &start,
- &offset, name_size);
- if (err < 0)
- goto failed;
-
- if (prefix == name_index && name_size == name_len &&
- strncmp(target, name, name_size) == 0) {
- /* found xattr */
- if (type & SQUASHFS_XATTR_VALUE_OOL) {
- __le64 xattr_val;
- u64 xattr;
- /* val is a reference to the real location */
- err = squashfs_read_metadata(sb, &val, &start,
- &offset, sizeof(val));
- if (err < 0)
- goto failed;
- err = squashfs_read_metadata(sb, &xattr_val,
- &start, &offset, sizeof(xattr_val));
- if (err < 0)
- goto failed;
- xattr = le64_to_cpu(xattr_val);
- start = SQUASHFS_XATTR_BLK(xattr) +
- msblk->xattr_table;
- offset = SQUASHFS_XATTR_OFFSET(xattr);
- }
- /* read xattr value */
- err = squashfs_read_metadata(sb, &val, &start, &offset,
- sizeof(val));
- if (err < 0)
- goto failed;
-
- vsize = le32_to_cpu(val.vsize);
- if (buffer) {
- if (vsize > buffer_size) {
- err = -ERANGE;
- goto failed;
- }
- err = squashfs_read_metadata(sb, buffer, &start,
- &offset, vsize);
- if (err < 0)
- goto failed;
- }
- break;
- }
-
- /* no match, skip remaining xattr entry */
- err = squashfs_read_metadata(sb, &val, &start, &offset,
- sizeof(val));
- if (err < 0)
- goto failed;
- err = squashfs_read_metadata(sb, NULL, &start, &offset,
- le32_to_cpu(val.vsize));
- if (err < 0)
- goto failed;
- }
- err = count ? vsize : -ENODATA;
-
-failed:
- kfree(target);
- return err;
-}
-
-
-/*
- * User namespace support
- */
-static size_t squashfs_user_list(struct dentry *d, char *list, size_t list_size,
- const char *name, size_t name_len, int type)
-{
- if (list && XATTR_USER_PREFIX_LEN <= list_size)
- memcpy(list, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
- return XATTR_USER_PREFIX_LEN;
-}
-
-static int squashfs_user_get(struct dentry *d, const char *name, void *buffer,
- size_t size, int type)
-{
- if (name[0] == '\0')
- return -EINVAL;
-
- return squashfs_xattr_get(d->d_inode, SQUASHFS_XATTR_USER, name,
- buffer, size);
-}
-
-static const struct xattr_handler squashfs_xattr_user_handler = {
- .prefix = XATTR_USER_PREFIX,
- .list = squashfs_user_list,
- .get = squashfs_user_get
-};
-
-/*
- * Trusted namespace support
- */
-static size_t squashfs_trusted_list(struct dentry *d, char *list,
- size_t list_size, const char *name, size_t name_len, int type)
-{
- if (!capable(CAP_SYS_ADMIN))
- return 0;
-
- if (list && XATTR_TRUSTED_PREFIX_LEN <= list_size)
- memcpy(list, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
- return XATTR_TRUSTED_PREFIX_LEN;
-}
-
-static int squashfs_trusted_get(struct dentry *d, const char *name,
- void *buffer, size_t size, int type)
-{
- if (name[0] == '\0')
- return -EINVAL;
-
- return squashfs_xattr_get(d->d_inode, SQUASHFS_XATTR_TRUSTED, name,
- buffer, size);
-}
-
-static const struct xattr_handler squashfs_xattr_trusted_handler = {
- .prefix = XATTR_TRUSTED_PREFIX,
- .list = squashfs_trusted_list,
- .get = squashfs_trusted_get
-};
-
-/*
- * Security namespace support
- */
-static size_t squashfs_security_list(struct dentry *d, char *list,
- size_t list_size, const char *name, size_t name_len, int type)
-{
- if (list && XATTR_SECURITY_PREFIX_LEN <= list_size)
- memcpy(list, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN);
- return XATTR_SECURITY_PREFIX_LEN;
-}
-
-static int squashfs_security_get(struct dentry *d, const char *name,
- void *buffer, size_t size, int type)
-{
- if (name[0] == '\0')
- return -EINVAL;
-
- return squashfs_xattr_get(d->d_inode, SQUASHFS_XATTR_SECURITY, name,
- buffer, size);
-}
-
-static const struct xattr_handler squashfs_xattr_security_handler = {
- .prefix = XATTR_SECURITY_PREFIX,
- .list = squashfs_security_list,
- .get = squashfs_security_get
-};
-
-static const struct xattr_handler *squashfs_xattr_handler(int type)
-{
- if (type & ~(SQUASHFS_XATTR_PREFIX_MASK | SQUASHFS_XATTR_VALUE_OOL))
- /* ignore unrecognised type */
- return NULL;
-
- switch (type & SQUASHFS_XATTR_PREFIX_MASK) {
- case SQUASHFS_XATTR_USER:
- return &squashfs_xattr_user_handler;
- case SQUASHFS_XATTR_TRUSTED:
- return &squashfs_xattr_trusted_handler;
- case SQUASHFS_XATTR_SECURITY:
- return &squashfs_xattr_security_handler;
- default:
- /* ignore unrecognised type */
- return NULL;
- }
-}
-
-const struct xattr_handler *squashfs_xattr_handlers[] = {
- &squashfs_xattr_user_handler,
- &squashfs_xattr_trusted_handler,
- &squashfs_xattr_security_handler,
- NULL
-};
-
diff --git a/ANDROID_3.4.5/fs/squashfs/xattr.h b/ANDROID_3.4.5/fs/squashfs/xattr.h
deleted file mode 100644
index c83f5d9e..00000000
--- a/ANDROID_3.4.5/fs/squashfs/xattr.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2010
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * xattr.h
- */
-
-#ifdef CONFIG_SQUASHFS_XATTR
-extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
- u64 *, int *);
-extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
- unsigned int *, unsigned long long *);
-#else
-static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb,
- u64 start, u64 *xattr_table_start, int *xattr_ids)
-{
- ERROR("Xattrs in filesystem, these will be ignored\n");
- *xattr_table_start = start;
- return ERR_PTR(-ENOTSUPP);
-}
-
-static inline int squashfs_xattr_lookup(struct super_block *sb,
- unsigned int index, int *count, unsigned int *size,
- unsigned long long *xattr)
-{
- return 0;
-}
-#define squashfs_listxattr NULL
-#define generic_getxattr NULL
-#define squashfs_xattr_handlers NULL
-#endif
diff --git a/ANDROID_3.4.5/fs/squashfs/xattr_id.c b/ANDROID_3.4.5/fs/squashfs/xattr_id.c
deleted file mode 100644
index c89607d6..00000000
--- a/ANDROID_3.4.5/fs/squashfs/xattr_id.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2010
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * xattr_id.c
- */
-
-/*
- * This file implements code to map the 32-bit xattr id stored in the inode
- * into the on disk location of the xattr data.
- */
-
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-#include "xattr.h"
-
-/*
- * Map xattr id using the xattr id look up table
- */
-int squashfs_xattr_lookup(struct super_block *sb, unsigned int index,
- int *count, unsigned int *size, unsigned long long *xattr)
-{
- struct squashfs_sb_info *msblk = sb->s_fs_info;
- int block = SQUASHFS_XATTR_BLOCK(index);
- int offset = SQUASHFS_XATTR_BLOCK_OFFSET(index);
- u64 start_block = le64_to_cpu(msblk->xattr_id_table[block]);
- struct squashfs_xattr_id id;
- int err;
-
- err = squashfs_read_metadata(sb, &id, &start_block, &offset,
- sizeof(id));
- if (err < 0)
- return err;
-
- *xattr = le64_to_cpu(id.xattr);
- *size = le32_to_cpu(id.size);
- *count = le32_to_cpu(id.count);
- return 0;
-}
-
-
-/*
- * Read uncompressed xattr id lookup table indexes from disk into memory
- */
-__le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start,
- u64 *xattr_table_start, int *xattr_ids)
-{
- unsigned int len;
- struct squashfs_xattr_id_table *id_table;
-
- id_table = squashfs_read_table(sb, start, sizeof(*id_table));
- if (IS_ERR(id_table))
- return (__le64 *) id_table;
-
- *xattr_table_start = le64_to_cpu(id_table->xattr_table_start);
- *xattr_ids = le32_to_cpu(id_table->xattr_ids);
- kfree(id_table);
-
- /* Sanity check values */
-
- /* there is always at least one xattr id */
- if (*xattr_ids == 0)
- return ERR_PTR(-EINVAL);
-
- /* xattr_table should be less than start */
- if (*xattr_table_start >= start)
- return ERR_PTR(-EINVAL);
-
- len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids);
-
- TRACE("In read_xattr_index_table, length %d\n", len);
-
- return squashfs_read_table(sb, start + sizeof(*id_table), len);
-}
diff --git a/ANDROID_3.4.5/fs/squashfs/xz_wrapper.c b/ANDROID_3.4.5/fs/squashfs/xz_wrapper.c
deleted file mode 100644
index 1760b7d1..00000000
--- a/ANDROID_3.4.5/fs/squashfs/xz_wrapper.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * xz_wrapper.c
- */
-
-
-#include <linux/mutex.h>
-#include <linux/buffer_head.h>
-#include <linux/slab.h>
-#include <linux/xz.h>
-#include <linux/bitops.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-#include "decompressor.h"
-
-struct squashfs_xz {
- struct xz_dec *state;
- struct xz_buf buf;
-};
-
-struct comp_opts {
- __le32 dictionary_size;
- __le32 flags;
-};
-
-static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff,
- int len)
-{
- struct comp_opts *comp_opts = buff;
- struct squashfs_xz *stream;
- int dict_size = msblk->block_size;
- int err, n;
-
- if (comp_opts) {
- /* check compressor options are the expected length */
- if (len < sizeof(*comp_opts)) {
- err = -EIO;
- goto failed;
- }
-
- dict_size = le32_to_cpu(comp_opts->dictionary_size);
-
- /* the dictionary size should be 2^n or 2^n+2^(n+1) */
- n = ffs(dict_size) - 1;
- if (dict_size != (1 << n) && dict_size != (1 << n) +
- (1 << (n + 1))) {
- err = -EIO;
- goto failed;
- }
- }
-
- dict_size = max_t(int, dict_size, SQUASHFS_METADATA_SIZE);
-
- stream = kmalloc(sizeof(*stream), GFP_KERNEL);
- if (stream == NULL) {
- err = -ENOMEM;
- goto failed;
- }
-
- stream->state = xz_dec_init(XZ_PREALLOC, dict_size);
- if (stream->state == NULL) {
- kfree(stream);
- err = -ENOMEM;
- goto failed;
- }
-
- return stream;
-
-failed:
- ERROR("Failed to initialise xz decompressor\n");
- return ERR_PTR(err);
-}
-
-
-static void squashfs_xz_free(void *strm)
-{
- struct squashfs_xz *stream = strm;
-
- if (stream) {
- xz_dec_end(stream->state);
- kfree(stream);
- }
-}
-
-
-static int squashfs_xz_uncompress(struct squashfs_sb_info *msblk, void **buffer,
- struct buffer_head **bh, int b, int offset, int length, int srclength,
- int pages)
-{
- enum xz_ret xz_err;
- int avail, total = 0, k = 0, page = 0;
- struct squashfs_xz *stream = msblk->stream;
-
- mutex_lock(&msblk->read_data_mutex);
-
- xz_dec_reset(stream->state);
- stream->buf.in_pos = 0;
- stream->buf.in_size = 0;
- stream->buf.out_pos = 0;
- stream->buf.out_size = PAGE_CACHE_SIZE;
- stream->buf.out = buffer[page++];
-
- do {
- if (stream->buf.in_pos == stream->buf.in_size && k < b) {
- avail = min(length, msblk->devblksize - offset);
- length -= avail;
- wait_on_buffer(bh[k]);
- if (!buffer_uptodate(bh[k]))
- goto release_mutex;
-
- stream->buf.in = bh[k]->b_data + offset;
- stream->buf.in_size = avail;
- stream->buf.in_pos = 0;
- offset = 0;
- }
-
- if (stream->buf.out_pos == stream->buf.out_size
- && page < pages) {
- stream->buf.out = buffer[page++];
- stream->buf.out_pos = 0;
- total += PAGE_CACHE_SIZE;
- }
-
- xz_err = xz_dec_run(stream->state, &stream->buf);
-
- if (stream->buf.in_pos == stream->buf.in_size && k < b)
- put_bh(bh[k++]);
- } while (xz_err == XZ_OK);
-
- if (xz_err != XZ_STREAM_END) {
- ERROR("xz_dec_run error, data probably corrupt\n");
- goto release_mutex;
- }
-
- if (k < b) {
- ERROR("xz_uncompress error, input remaining\n");
- goto release_mutex;
- }
-
- total += stream->buf.out_pos;
- mutex_unlock(&msblk->read_data_mutex);
- return total;
-
-release_mutex:
- mutex_unlock(&msblk->read_data_mutex);
-
- for (; k < b; k++)
- put_bh(bh[k]);
-
- return -EIO;
-}
-
-const struct squashfs_decompressor squashfs_xz_comp_ops = {
- .init = squashfs_xz_init,
- .free = squashfs_xz_free,
- .decompress = squashfs_xz_uncompress,
- .id = XZ_COMPRESSION,
- .name = "xz",
- .supported = 1
-};
diff --git a/ANDROID_3.4.5/fs/squashfs/zlib_wrapper.c b/ANDROID_3.4.5/fs/squashfs/zlib_wrapper.c
deleted file mode 100644
index 55d918fd..00000000
--- a/ANDROID_3.4.5/fs/squashfs/zlib_wrapper.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Squashfs - a compressed read only filesystem for Linux
- *
- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- * Phillip Lougher <phillip@squashfs.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * zlib_wrapper.c
- */
-
-
-#include <linux/mutex.h>
-#include <linux/buffer_head.h>
-#include <linux/slab.h>
-#include <linux/zlib.h>
-#include <linux/vmalloc.h>
-
-#include "squashfs_fs.h"
-#include "squashfs_fs_sb.h"
-#include "squashfs.h"
-#include "decompressor.h"
-
-static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len)
-{
- z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
- if (stream == NULL)
- goto failed;
- stream->workspace = vmalloc(zlib_inflate_workspacesize());
- if (stream->workspace == NULL)
- goto failed;
-
- return stream;
-
-failed:
- ERROR("Failed to allocate zlib workspace\n");
- kfree(stream);
- return ERR_PTR(-ENOMEM);
-}
-
-
-static void zlib_free(void *strm)
-{
- z_stream *stream = strm;
-
- if (stream)
- vfree(stream->workspace);
- kfree(stream);
-}
-
-
-static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
- struct buffer_head **bh, int b, int offset, int length, int srclength,
- int pages)
-{
- int zlib_err, zlib_init = 0;
- int k = 0, page = 0;
- z_stream *stream = msblk->stream;
-
- mutex_lock(&msblk->read_data_mutex);
-
- stream->avail_out = 0;
- stream->avail_in = 0;
-
- do {
- if (stream->avail_in == 0 && k < b) {
- int avail = min(length, msblk->devblksize - offset);
- length -= avail;
- wait_on_buffer(bh[k]);
- if (!buffer_uptodate(bh[k]))
- goto release_mutex;
-
- stream->next_in = bh[k]->b_data + offset;
- stream->avail_in = avail;
- offset = 0;
- }
-
- if (stream->avail_out == 0 && page < pages) {
- stream->next_out = buffer[page++];
- stream->avail_out = PAGE_CACHE_SIZE;
- }
-
- if (!zlib_init) {
- zlib_err = zlib_inflateInit(stream);
- if (zlib_err != Z_OK) {
- ERROR("zlib_inflateInit returned unexpected "
- "result 0x%x, srclength %d\n",
- zlib_err, srclength);
- goto release_mutex;
- }
- zlib_init = 1;
- }
-
- zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
-
- if (stream->avail_in == 0 && k < b)
- put_bh(bh[k++]);
- } while (zlib_err == Z_OK);
-
- if (zlib_err != Z_STREAM_END) {
- ERROR("zlib_inflate error, data probably corrupt\n");
- goto release_mutex;
- }
-
- zlib_err = zlib_inflateEnd(stream);
- if (zlib_err != Z_OK) {
- ERROR("zlib_inflate error, data probably corrupt\n");
- goto release_mutex;
- }
-
- if (k < b) {
- ERROR("zlib_uncompress error, data remaining\n");
- goto release_mutex;
- }
-
- length = stream->total_out;
- mutex_unlock(&msblk->read_data_mutex);
- return length;
-
-release_mutex:
- mutex_unlock(&msblk->read_data_mutex);
-
- for (; k < b; k++)
- put_bh(bh[k]);
-
- return -EIO;
-}
-
-const struct squashfs_decompressor squashfs_zlib_comp_ops = {
- .init = zlib_init,
- .free = zlib_free,
- .decompress = zlib_uncompress,
- .id = ZLIB_COMPRESSION,
- .name = "zlib",
- .supported = 1
-};
-