diff options
Diffstat (limited to 'meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch')
-rw-r--r-- | meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch | 6727 |
1 files changed, 0 insertions, 6727 deletions
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch b/meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch deleted file mode 100644 index 4de9839c7..000000000 --- a/meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch +++ /dev/null @@ -1,6727 +0,0 @@ -diff -uNr a/fs/Kconfig b/fs/Kconfig ---- a/fs/Kconfig 2008-07-28 19:40:31.000000000 -0700 -+++ b/fs/Kconfig 2008-08-13 16:19:56.000000000 -0700 -@@ -1348,6 +1348,56 @@ - - If unsure, say N. - -+config SQUASHFS -+ tristate "SquashFS 3.3 - Squashed file system support" -+ select ZLIB_INFLATE -+ help -+ Saying Y here includes support for SquashFS 3.3 (a Compressed -+ Read-Only File System). Squashfs is a highly compressed read-only -+ filesystem for Linux. It uses zlib compression to compress both -+ files, inodes and directories. Inodes in the system are very small -+ and all blocks are packed to minimise data overhead. Block sizes -+ greater than 4K are supported up to a maximum of 1 Mbytes (default -+ block size 128K). SquashFS 3.3 supports 64 bit filesystems and files -+ (larger than 4GB), full uid/gid information, hard links and timestamps. -+ -+ Squashfs is intended for general read-only filesystem use, for -+ archival use (i.e. in cases where a .tar.gz file may be used), and in -+ embedded systems where low overhead is needed. Further information -+ and filesystem tools are available from http://squashfs.sourceforge.net. -+ -+ If you want to compile this as a module ( = code which can be -+ inserted in and removed from the running kernel whenever you want), -+ say M here and read <file:Documentation/modules.txt>. The module -+ will be called squashfs. Note that the root file system (the one -+ containing the directory /) cannot be compiled as a module. -+ -+ If unsure, say N. -+ -+config SQUASHFS_EMBEDDED -+ -+ bool "Additional option for memory-constrained systems" -+ depends on SQUASHFS -+ default n -+ 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. -+ - config VXFS_FS - tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" - depends on BLOCK -diff -uNr a/fs/Kconfig.orig b/fs/Kconfig.orig ---- a/fs/Kconfig.orig 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/Kconfig.orig 2008-07-28 19:40:31.000000000 -0700 -@@ -0,0 +1,2097 @@ -+# -+# File system configuration -+# -+ -+menu "File systems" -+ -+if BLOCK -+ -+config EXT2_FS -+ tristate "Second extended fs support" -+ help -+ Ext2 is a standard Linux file system for hard disks. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called ext2. -+ -+ If unsure, say Y. -+ -+config EXT2_FS_XATTR -+ bool "Ext2 extended attributes" -+ depends on EXT2_FS -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ <http://acl.bestbits.at/> for details). -+ -+ If unsure, say N. -+ -+config EXT2_FS_POSIX_ACL -+ bool "Ext2 POSIX Access Control Lists" -+ depends on EXT2_FS_XATTR -+ select FS_POSIX_ACL -+ help -+ Posix Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the Posix ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N -+ -+config EXT2_FS_SECURITY -+ bool "Ext2 Security Labels" -+ depends on EXT2_FS_XATTR -+ help -+ Security labels support alternative access control models -+ implemented by security modules like SELinux. This option -+ enables an extended attribute handler for file security -+ labels in the ext2 filesystem. -+ -+ If you are not using a security module that requires using -+ extended attributes for file security labels, say N. -+ -+config EXT2_FS_XIP -+ bool "Ext2 execute in place support" -+ depends on EXT2_FS && MMU -+ help -+ Execute in place can be used on memory-backed block devices. If you -+ enable this option, you can select to mount block devices which are -+ capable of this feature without using the page cache. -+ -+ If you do not use a block device that is capable of using this, -+ or if unsure, say N. -+ -+config FS_XIP -+# execute in place -+ bool -+ depends on EXT2_FS_XIP -+ default y -+ -+config EXT3_FS -+ tristate "Ext3 journalling file system support" -+ select JBD -+ help -+ This is the journalling version of the Second extended file system -+ (often called ext3), the de facto standard Linux file system -+ (method to organize files on a storage device) for hard disks. -+ -+ The journalling code included in this driver means you do not have -+ to run e2fsck (file system checker) on your file systems after a -+ crash. The journal keeps track of any changes that were being made -+ at the time the system crashed, and can ensure that your file system -+ is consistent without the need for a lengthy check. -+ -+ Other than adding the journal to the file system, the on-disk format -+ of ext3 is identical to ext2. It is possible to freely switch -+ between using the ext3 driver and the ext2 driver, as long as the -+ file system has been cleanly unmounted, or e2fsck is run on the file -+ system. -+ -+ To add a journal on an existing ext2 file system or change the -+ behavior of ext3 file systems, you can use the tune2fs utility ("man -+ tune2fs"). To modify attributes of files and directories on ext3 -+ file systems, use chattr ("man chattr"). You need to be using -+ e2fsprogs version 1.20 or later in order to create ext3 journals -+ (available at <http://sourceforge.net/projects/e2fsprogs/>). -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called ext3. -+ -+config EXT3_FS_XATTR -+ bool "Ext3 extended attributes" -+ depends on EXT3_FS -+ default y -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ <http://acl.bestbits.at/> for details). -+ -+ If unsure, say N. -+ -+ You need this for POSIX ACL support on ext3. -+ -+config EXT3_FS_POSIX_ACL -+ bool "Ext3 POSIX Access Control Lists" -+ depends on EXT3_FS_XATTR -+ select FS_POSIX_ACL -+ help -+ Posix Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the Posix ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N -+ -+config EXT3_FS_SECURITY -+ bool "Ext3 Security Labels" -+ depends on EXT3_FS_XATTR -+ help -+ Security labels support alternative access control models -+ implemented by security modules like SELinux. This option -+ enables an extended attribute handler for file security -+ labels in the ext3 filesystem. -+ -+ If you are not using a security module that requires using -+ extended attributes for file security labels, say N. -+ -+config EXT4DEV_FS -+ tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ select JBD2 -+ select CRC16 -+ help -+ Ext4dev is a predecessor filesystem of the next generation -+ extended fs ext4, based on ext3 filesystem code. It will be -+ renamed ext4 fs later, once ext4dev is mature and stabilized. -+ -+ Unlike the change from ext2 filesystem to ext3 filesystem, -+ the on-disk format of ext4dev is not the same as ext3 any more: -+ it is based on extent maps and it supports 48-bit physical block -+ numbers. These combined on-disk format changes will allow -+ ext4dev/ext4 to handle more than 16 TB filesystem volumes -- -+ a hard limit that ext3 cannot overcome without changing the -+ on-disk format. -+ -+ Other than extent maps and 48-bit block numbers, ext4dev also is -+ likely to have other new features such as persistent preallocation, -+ high resolution time stamps, and larger file support etc. These -+ features will be added to ext4dev gradually. -+ -+ To compile this file system support as a module, choose M here. The -+ module will be called ext4dev. -+ -+ If unsure, say N. -+ -+config EXT4DEV_FS_XATTR -+ bool "Ext4dev extended attributes" -+ depends on EXT4DEV_FS -+ default y -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ <http://acl.bestbits.at/> for details). -+ -+ If unsure, say N. -+ -+ You need this for POSIX ACL support on ext4dev/ext4. -+ -+config EXT4DEV_FS_POSIX_ACL -+ bool "Ext4dev POSIX Access Control Lists" -+ depends on EXT4DEV_FS_XATTR -+ select FS_POSIX_ACL -+ help -+ POSIX Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the POSIX ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N -+ -+config EXT4DEV_FS_SECURITY -+ bool "Ext4dev Security Labels" -+ depends on EXT4DEV_FS_XATTR -+ help -+ Security labels support alternative access control models -+ implemented by security modules like SELinux. This option -+ enables an extended attribute handler for file security -+ labels in the ext4dev/ext4 filesystem. -+ -+ If you are not using a security module that requires using -+ extended attributes for file security labels, say N. -+ -+config JBD -+ tristate -+ help -+ This is a generic journalling layer for block devices. It is -+ currently used by the ext3 and OCFS2 file systems, but it could -+ also be used to add journal support to other file systems or block -+ devices such as RAID or LVM. -+ -+ If you are using the ext3 or OCFS2 file systems, you need to -+ say Y here. If you are not using ext3 OCFS2 then you will probably -+ want to say N. -+ -+ To compile this device as a module, choose M here: the module will be -+ called jbd. If you are compiling ext3 or OCFS2 into the kernel, -+ you cannot compile this code as a module. -+ -+config JBD_DEBUG -+ bool "JBD (ext3) debugging support" -+ depends on JBD && DEBUG_FS -+ help -+ If you are using the ext3 journaled file system (or potentially any -+ other file system/device using JBD), this option allows you to -+ enable debugging output while the system is running, in order to -+ help track down any problems you are having. By default the -+ debugging output will be turned off. -+ -+ If you select Y here, then you will be able to turn on debugging -+ with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a -+ number between 1 and 5, the higher the number, the more debugging -+ output is generated. To turn debugging off again, do -+ "echo 0 > /sys/kernel/debug/jbd/jbd-debug". -+ -+config JBD2 -+ tristate -+ select CRC32 -+ help -+ This is a generic journaling layer for block devices that support -+ both 32-bit and 64-bit block numbers. It is currently used by -+ the ext4dev/ext4 filesystem, but it could also be used to add -+ journal support to other file systems or block devices such -+ as RAID or LVM. -+ -+ If you are using ext4dev/ext4, you need to say Y here. If you are not -+ using ext4dev/ext4 then you will probably want to say N. -+ -+ To compile this device as a module, choose M here. The module will be -+ called jbd2. If you are compiling ext4dev/ext4 into the kernel, -+ you cannot compile this code as a module. -+ -+config JBD2_DEBUG -+ bool "JBD2 (ext4dev/ext4) debugging support" -+ depends on JBD2 && DEBUG_FS -+ help -+ If you are using the ext4dev/ext4 journaled file system (or -+ potentially any other filesystem/device using JBD2), this option -+ allows you to enable debugging output while the system is running, -+ in order to help track down any problems you are having. -+ By default, the debugging output will be turned off. -+ -+ If you select Y here, then you will be able to turn on debugging -+ with "echo N > /sys/kernel/debug/jbd2/jbd2-debug", where N is a -+ number between 1 and 5. The higher the number, the more debugging -+ output is generated. To turn debugging off again, do -+ "echo 0 > /sys/kernel/debug/jbd2/jbd2-debug". -+ -+config FS_MBCACHE -+# Meta block cache for Extended Attributes (ext2/ext3/ext4) -+ tristate -+ depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4DEV_FS_XATTR -+ default y if EXT2_FS=y || EXT3_FS=y || EXT4DEV_FS=y -+ default m if EXT2_FS=m || EXT3_FS=m || EXT4DEV_FS=m -+ -+config REISERFS_FS -+ tristate "Reiserfs support" -+ help -+ Stores not just filenames but the files themselves in a balanced -+ tree. Uses journalling. -+ -+ Balanced trees are more efficient than traditional file system -+ architectural foundations. -+ -+ In general, ReiserFS is as fast as ext2, but is very efficient with -+ large directories and small files. Additional patches are needed -+ for NFS and quotas, please see <http://www.namesys.com/> for links. -+ -+ It is more easily extended to have features currently found in -+ database and keyword search systems than block allocation based file -+ systems are. The next version will be so extended, and will support -+ plugins consistent with our motto ``It takes more than a license to -+ make source code open.'' -+ -+ Read <http://www.namesys.com/> to learn more about reiserfs. -+ -+ Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com. -+ -+ If you like it, you can pay us to add new features to it that you -+ need, buy a support contract, or pay us to port it to another OS. -+ -+config REISERFS_CHECK -+ bool "Enable reiserfs debug mode" -+ depends on REISERFS_FS -+ help -+ If you set this to Y, then ReiserFS will perform every check it can -+ possibly imagine of its internal consistency throughout its -+ operation. It will also go substantially slower. More than once we -+ have forgotten that this was on, and then gone despondent over the -+ latest benchmarks.:-) Use of this option allows our team to go all -+ out in checking for consistency when debugging without fear of its -+ effect on end users. If you are on the verge of sending in a bug -+ report, say Y and you might get a useful error message. Almost -+ everyone should say N. -+ -+config REISERFS_PROC_INFO -+ bool "Stats in /proc/fs/reiserfs" -+ depends on REISERFS_FS && PROC_FS -+ help -+ Create under /proc/fs/reiserfs a hierarchy of files, displaying -+ various ReiserFS statistics and internal data at the expense of -+ making your kernel or module slightly larger (+8 KB). This also -+ increases the amount of kernel memory required for each mount. -+ Almost everyone but ReiserFS developers and people fine-tuning -+ reiserfs or tracing problems should say N. -+ -+config REISERFS_FS_XATTR -+ bool "ReiserFS extended attributes" -+ depends on REISERFS_FS -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ <http://acl.bestbits.at/> for details). -+ -+ If unsure, say N. -+ -+config REISERFS_FS_POSIX_ACL -+ bool "ReiserFS POSIX Access Control Lists" -+ depends on REISERFS_FS_XATTR -+ select FS_POSIX_ACL -+ help -+ Posix Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the Posix ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N -+ -+config REISERFS_FS_SECURITY -+ bool "ReiserFS Security Labels" -+ depends on REISERFS_FS_XATTR -+ help -+ Security labels support alternative access control models -+ implemented by security modules like SELinux. This option -+ enables an extended attribute handler for file security -+ labels in the ReiserFS filesystem. -+ -+ If you are not using a security module that requires using -+ extended attributes for file security labels, say N. -+ -+config JFS_FS -+ tristate "JFS filesystem support" -+ select NLS -+ help -+ This is a port of IBM's Journaled Filesystem . More information is -+ available in the file <file:Documentation/filesystems/jfs.txt>. -+ -+ If you do not intend to use the JFS filesystem, say N. -+ -+config JFS_POSIX_ACL -+ bool "JFS POSIX Access Control Lists" -+ depends on JFS_FS -+ select FS_POSIX_ACL -+ help -+ Posix Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the Posix ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N -+ -+config JFS_SECURITY -+ bool "JFS Security Labels" -+ depends on JFS_FS -+ help -+ Security labels support alternative access control models -+ implemented by security modules like SELinux. This option -+ enables an extended attribute handler for file security -+ labels in the jfs filesystem. -+ -+ If you are not using a security module that requires using -+ extended attributes for file security labels, say N. -+ -+config JFS_DEBUG -+ bool "JFS debugging" -+ depends on JFS_FS -+ help -+ If you are experiencing any problems with the JFS filesystem, say -+ Y here. This will result in additional debugging messages to be -+ written to the system log. Under normal circumstances, this -+ results in very little overhead. -+ -+config JFS_STATISTICS -+ bool "JFS statistics" -+ depends on JFS_FS -+ help -+ Enabling this option will cause statistics from the JFS file system -+ to be made available to the user in the /proc/fs/jfs/ directory. -+ -+config FS_POSIX_ACL -+# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/nfs4) -+# -+# NOTE: you can implement Posix ACLs without these helpers (XFS does). -+# Never use this symbol for ifdefs. -+# -+ bool -+ default n -+ -+source "fs/xfs/Kconfig" -+source "fs/gfs2/Kconfig" -+ -+config OCFS2_FS -+ tristate "OCFS2 file system support" -+ depends on NET && SYSFS -+ select CONFIGFS_FS -+ select JBD -+ select CRC32 -+ help -+ OCFS2 is a general purpose extent based shared disk cluster file -+ system with many similarities to ext3. It supports 64 bit inode -+ numbers, and has automatically extending metadata groups which may -+ also make it attractive for non-clustered use. -+ -+ You'll want to install the ocfs2-tools package in order to at least -+ get "mount.ocfs2". -+ -+ Project web page: http://oss.oracle.com/projects/ocfs2 -+ Tools web page: http://oss.oracle.com/projects/ocfs2-tools -+ OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/ -+ -+ For more information on OCFS2, see the file -+ <file:Documentation/filesystems/ocfs2.txt>. -+ -+config OCFS2_FS_O2CB -+ tristate "O2CB Kernelspace Clustering" -+ depends on OCFS2_FS -+ default y -+ help -+ OCFS2 includes a simple kernelspace clustering package, the OCFS2 -+ Cluster Base. It only requires a very small userspace component -+ to configure it. This comes with the standard ocfs2-tools package. -+ O2CB is limited to maintaining a cluster for OCFS2 file systems. -+ It cannot manage any other cluster applications. -+ -+ It is always safe to say Y here, as the clustering method is -+ run-time selectable. -+ -+config OCFS2_FS_USERSPACE_CLUSTER -+ tristate "OCFS2 Userspace Clustering" -+ depends on OCFS2_FS && DLM -+ default y -+ help -+ This option will allow OCFS2 to use userspace clustering services -+ in conjunction with the DLM in fs/dlm. If you are using a -+ userspace cluster manager, say Y here. -+ -+ It is safe to say Y, as the clustering method is run-time -+ selectable. -+ -+config OCFS2_FS_STATS -+ bool "OCFS2 statistics" -+ depends on OCFS2_FS -+ default y -+ help -+ This option allows some fs statistics to be captured. Enabling -+ this option may increase the memory consumption. -+ -+config OCFS2_DEBUG_MASKLOG -+ bool "OCFS2 logging support" -+ depends on OCFS2_FS -+ default y -+ help -+ The ocfs2 filesystem has an extensive logging system. The system -+ allows selection of events to log via files in /sys/o2cb/logmask/. -+ This option will enlarge your kernel, but it allows debugging of -+ ocfs2 filesystem issues. -+ -+config OCFS2_DEBUG_FS -+ bool "OCFS2 expensive checks" -+ depends on OCFS2_FS -+ default n -+ help -+ This option will enable expensive consistency checks. Enable -+ this option for debugging only as it is likely to decrease -+ performance of the filesystem. -+ -+endif # BLOCK -+ -+config DNOTIFY -+ bool "Dnotify support" -+ default y -+ help -+ Dnotify is a directory-based per-fd file change notification system -+ that uses signals to communicate events to user-space. There exist -+ superior alternatives, but some applications may still rely on -+ dnotify. -+ -+ If unsure, say Y. -+ -+config INOTIFY -+ bool "Inotify file change notification support" -+ default y -+ ---help--- -+ Say Y here to enable inotify support. Inotify is a file change -+ notification system and a replacement for dnotify. Inotify fixes -+ numerous shortcomings in dnotify and introduces several new features -+ including multiple file events, one-shot support, and unmount -+ notification. -+ -+ For more information, see <file:Documentation/filesystems/inotify.txt> -+ -+ If unsure, say Y. -+ -+config INOTIFY_USER -+ bool "Inotify support for userspace" -+ depends on INOTIFY -+ default y -+ ---help--- -+ Say Y here to enable inotify support for userspace, including the -+ associated system calls. Inotify allows monitoring of both files and -+ directories via a single open fd. Events are read from the file -+ descriptor, which is also select()- and poll()-able. -+ -+ For more information, see <file:Documentation/filesystems/inotify.txt> -+ -+ If unsure, say Y. -+ -+config QUOTA -+ bool "Quota support" -+ help -+ If you say Y here, you will be able to set per user limits for disk -+ usage (also called disk quotas). Currently, it works for the -+ ext2, ext3, and reiserfs file system. ext3 also supports journalled -+ quotas for which you don't need to run quotacheck(8) after an unclean -+ shutdown. -+ For further details, read the Quota mini-HOWTO, available from -+ <http://www.tldp.org/docs.html#howto>, or the documentation provided -+ with the quota tools. Probably the quota support is only useful for -+ multi user systems. If unsure, say N. -+ -+config QUOTA_NETLINK_INTERFACE -+ bool "Report quota messages through netlink interface" -+ depends on QUOTA && NET -+ help -+ If you say Y here, quota warnings (about exceeding softlimit, reaching -+ hardlimit, etc.) will be reported through netlink interface. If unsure, -+ say Y. -+ -+config PRINT_QUOTA_WARNING -+ bool "Print quota warnings to console (OBSOLETE)" -+ depends on QUOTA -+ default y -+ help -+ If you say Y here, quota warnings (about exceeding softlimit, reaching -+ hardlimit, etc.) will be printed to the process' controlling terminal. -+ Note that this behavior is currently deprecated and may go away in -+ future. Please use notification via netlink socket instead. -+ -+config QFMT_V1 -+ tristate "Old quota format support" -+ depends on QUOTA -+ help -+ This quota format was (is) used by kernels earlier than 2.4.22. If -+ you have quota working and you don't want to convert to new quota -+ format say Y here. -+ -+config QFMT_V2 -+ tristate "Quota format v2 support" -+ depends on QUOTA -+ help -+ This quota format allows using quotas with 32-bit UIDs/GIDs. If you -+ need this functionality say Y here. -+ -+config QUOTACTL -+ bool -+ depends on XFS_QUOTA || QUOTA -+ default y -+ -+config AUTOFS_FS -+ tristate "Kernel automounter support" -+ help -+ The automounter is a tool to automatically mount remote file systems -+ on demand. This implementation is partially kernel-based to reduce -+ overhead in the already-mounted case; this is unlike the BSD -+ automounter (amd), which is a pure user space daemon. -+ -+ To use the automounter you need the user-space tools from the autofs -+ package; you can find the location in <file:Documentation/Changes>. -+ You also want to answer Y to "NFS file system support", below. -+ -+ If you want to use the newer version of the automounter with more -+ features, say N here and say Y to "Kernel automounter v4 support", -+ below. -+ -+ To compile this support as a module, choose M here: the module will be -+ called autofs. -+ -+ If you are not a part of a fairly large, distributed network, you -+ probably do not need an automounter, and can say N here. -+ -+config AUTOFS4_FS -+ tristate "Kernel automounter version 4 support (also supports v3)" -+ help -+ The automounter is a tool to automatically mount remote file systems -+ on demand. This implementation is partially kernel-based to reduce -+ overhead in the already-mounted case; this is unlike the BSD -+ automounter (amd), which is a pure user space daemon. -+ -+ To use the automounter you need the user-space tools from -+ <ftp://ftp.kernel.org/pub/linux/daemons/autofs/v4/>; you also -+ want to answer Y to "NFS file system support", below. -+ -+ To compile this support as a module, choose M here: the module will be -+ called autofs4. You will need to add "alias autofs autofs4" to your -+ modules configuration file. -+ -+ If you are not a part of a fairly large, distributed network or -+ don't have a laptop which needs to dynamically reconfigure to the -+ local network, you probably do not need an automounter, and can say -+ N here. -+ -+config FUSE_FS -+ tristate "Filesystem in Userspace support" -+ help -+ With FUSE it is possible to implement a fully functional filesystem -+ in a userspace program. -+ -+ There's also companion library: libfuse. This library along with -+ utilities is available from the FUSE homepage: -+ <http://fuse.sourceforge.net/> -+ -+ See <file:Documentation/filesystems/fuse.txt> for more information. -+ See <file:Documentation/Changes> for needed library/utility version. -+ -+ If you want to develop a userspace FS, or if you want to use -+ a filesystem based on FUSE, answer Y or M. -+ -+config GENERIC_ACL -+ bool -+ select FS_POSIX_ACL -+ -+if BLOCK -+menu "CD-ROM/DVD Filesystems" -+ -+config ISO9660_FS -+ tristate "ISO 9660 CDROM file system support" -+ help -+ This is the standard file system used on CD-ROMs. It was previously -+ known as "High Sierra File System" and is called "hsfs" on other -+ Unix systems. The so-called Rock-Ridge extensions which allow for -+ long Unix filenames and symbolic links are also supported by this -+ driver. If you have a CD-ROM drive and want to do more with it than -+ just listen to audio CDs and watch its LEDs, say Y (and read -+ <file:Documentation/filesystems/isofs.txt> and the CD-ROM-HOWTO, -+ available from <http://www.tldp.org/docs.html#howto>), thereby -+ enlarging your kernel by about 27 KB; otherwise say N. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called isofs. -+ -+config JOLIET -+ bool "Microsoft Joliet CDROM extensions" -+ depends on ISO9660_FS -+ select NLS -+ help -+ Joliet is a Microsoft extension for the ISO 9660 CD-ROM file system -+ which allows for long filenames in unicode format (unicode is the -+ new 16 bit character code, successor to ASCII, which encodes the -+ characters of almost all languages of the world; see -+ <http://www.unicode.org/> for more information). Say Y here if you -+ want to be able to read Joliet CD-ROMs under Linux. -+ -+config ZISOFS -+ bool "Transparent decompression extension" -+ depends on ISO9660_FS -+ select ZLIB_INFLATE -+ help -+ This is a Linux-specific extension to RockRidge which lets you store -+ data in compressed form on a CD-ROM and have it transparently -+ decompressed when the CD-ROM is accessed. See -+ <http://www.kernel.org/pub/linux/utils/fs/zisofs/> for the tools -+ necessary to create such a filesystem. Say Y here if you want to be -+ able to read such compressed CD-ROMs. -+ -+config UDF_FS -+ tristate "UDF file system support" -+ select CRC_ITU_T -+ help -+ This is the new file system used on some CD-ROMs and DVDs. Say Y if -+ you intend to mount DVD discs or CDRW's written in packet mode, or -+ if written to by other UDF utilities, such as DirectCD. -+ Please read <file:Documentation/filesystems/udf.txt>. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called udf. -+ -+ If unsure, say N. -+ -+config UDF_NLS -+ bool -+ default y -+ depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y) -+ -+endmenu -+endif # BLOCK -+ -+if BLOCK -+menu "DOS/FAT/NT Filesystems" -+ -+config FAT_FS -+ tristate -+ select NLS -+ help -+ If you want to use one of the FAT-based file systems (the MS-DOS and -+ VFAT (Windows 95) file systems), then you must say Y or M here -+ to include FAT support. You will then be able to mount partitions or -+ diskettes with FAT-based file systems and transparently access the -+ files on them, i.e. MSDOS files will look and behave just like all -+ other Unix files. -+ -+ This FAT support is not a file system in itself, it only provides -+ the foundation for the other file systems. You will have to say Y or -+ M to at least one of "MSDOS fs support" or "VFAT fs support" in -+ order to make use of it. -+ -+ Another way to read and write MSDOS floppies and hard drive -+ partitions from within Linux (but not transparently) is with the -+ mtools ("man mtools") program suite. You don't need to say Y here in -+ order to do that. -+ -+ If you need to move large files on floppies between a DOS and a -+ Linux box, say Y here, mount the floppy under Linux with an MSDOS -+ file system and use GNU tar's M option. GNU tar is a program -+ available for Unix and DOS ("man tar" or "info tar"). -+ -+ The FAT support will enlarge your kernel by about 37 KB. If unsure, -+ say Y. -+ -+ To compile this as a module, choose M here: the module will be called -+ fat. Note that if you compile the FAT support as a module, you -+ cannot compile any of the FAT-based file systems into the kernel -+ -- they will have to be modules as well. -+ -+config MSDOS_FS -+ tristate "MSDOS fs support" -+ select FAT_FS -+ help -+ This allows you to mount MSDOS partitions of your hard drive (unless -+ they are compressed; to access compressed MSDOS partitions under -+ Linux, you can either use the DOS emulator DOSEMU, described in the -+ DOSEMU-HOWTO, available from -+ <http://www.tldp.org/docs.html#howto>, or try dmsdosfs in -+ <ftp://ibiblio.org/pub/Linux/system/filesystems/dosfs/>. If you -+ intend to use dosemu with a non-compressed MSDOS partition, say Y -+ here) and MSDOS floppies. This means that file access becomes -+ transparent, i.e. the MSDOS files look and behave just like all -+ other Unix files. -+ -+ If you have Windows 95 or Windows NT installed on your MSDOS -+ partitions, you should use the VFAT file system (say Y to "VFAT fs -+ support" below), or you will not be able to see the long filenames -+ generated by Windows 95 / Windows NT. -+ -+ This option will enlarge your kernel by about 7 KB. If unsure, -+ answer Y. This will only work if you said Y to "DOS FAT fs support" -+ as well. To compile this as a module, choose M here: the module will -+ be called msdos. -+ -+config VFAT_FS -+ tristate "VFAT (Windows-95) fs support" -+ select FAT_FS -+ help -+ This option provides support for normal Windows file systems with -+ long filenames. That includes non-compressed FAT-based file systems -+ used by Windows 95, Windows 98, Windows NT 4.0, and the Unix -+ programs from the mtools package. -+ -+ The VFAT support enlarges your kernel by about 10 KB and it only -+ works if you said Y to the "DOS FAT fs support" above. Please read -+ the file <file:Documentation/filesystems/vfat.txt> for details. If -+ unsure, say Y. -+ -+ To compile this as a module, choose M here: the module will be called -+ vfat. -+ -+config FAT_DEFAULT_CODEPAGE -+ int "Default codepage for FAT" -+ depends on MSDOS_FS || VFAT_FS -+ default 437 -+ help -+ This option should be set to the codepage of your FAT filesystems. -+ It can be overridden with the "codepage" mount option. -+ See <file:Documentation/filesystems/vfat.txt> for more information. -+ -+config FAT_DEFAULT_IOCHARSET -+ string "Default iocharset for FAT" -+ depends on VFAT_FS -+ default "iso8859-1" -+ help -+ Set this to the default input/output character set you'd -+ like FAT to use. It should probably match the character set -+ that most of your FAT filesystems use, and can be overridden -+ with the "iocharset" mount option for FAT filesystems. -+ Note that "utf8" is not recommended for FAT filesystems. -+ If unsure, you shouldn't set "utf8" here. -+ See <file:Documentation/filesystems/vfat.txt> for more information. -+ -+config NTFS_FS -+ tristate "NTFS file system support" -+ select NLS -+ help -+ NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003. -+ -+ Saying Y or M here enables read support. There is partial, but -+ safe, write support available. For write support you must also -+ say Y to "NTFS write support" below. -+ -+ There are also a number of user-space tools available, called -+ ntfsprogs. These include ntfsundelete and ntfsresize, that work -+ without NTFS support enabled in the kernel. -+ -+ This is a rewrite from scratch of Linux NTFS support and replaced -+ the old NTFS code starting with Linux 2.5.11. A backport to -+ the Linux 2.4 kernel series is separately available as a patch -+ from the project web site. -+ -+ For more information see <file:Documentation/filesystems/ntfs.txt> -+ and <http://www.linux-ntfs.org/>. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called ntfs. -+ -+ If you are not using Windows NT, 2000, XP or 2003 in addition to -+ Linux on your computer it is safe to say N. -+ -+config NTFS_DEBUG -+ bool "NTFS debugging support" -+ depends on NTFS_FS -+ help -+ If you are experiencing any problems with the NTFS file system, say -+ Y here. This will result in additional consistency checks to be -+ performed by the driver as well as additional debugging messages to -+ be written to the system log. Note that debugging messages are -+ disabled by default. To enable them, supply the option debug_msgs=1 -+ at the kernel command line when booting the kernel or as an option -+ to insmod when loading the ntfs module. Once the driver is active, -+ you can enable debugging messages by doing (as root): -+ echo 1 > /proc/sys/fs/ntfs-debug -+ Replacing the "1" with "0" would disable debug messages. -+ -+ If you leave debugging messages disabled, this results in little -+ overhead, but enabling debug messages results in very significant -+ slowdown of the system. -+ -+ When reporting bugs, please try to have available a full dump of -+ debugging messages while the misbehaviour was occurring. -+ -+config NTFS_RW -+ bool "NTFS write support" -+ depends on NTFS_FS -+ help -+ This enables the partial, but safe, write support in the NTFS driver. -+ -+ The only supported operation is overwriting existing files, without -+ changing the file length. No file or directory creation, deletion or -+ renaming is possible. Note only non-resident files can be written to -+ so you may find that some very small files (<500 bytes or so) cannot -+ be written to. -+ -+ While we cannot guarantee that it will not damage any data, we have -+ so far not received a single report where the driver would have -+ damaged someones data so we assume it is perfectly safe to use. -+ -+ Note: While write support is safe in this version (a rewrite from -+ scratch of the NTFS support), it should be noted that the old NTFS -+ write support, included in Linux 2.5.10 and before (since 1997), -+ is not safe. -+ -+ This is currently useful with TopologiLinux. TopologiLinux is run -+ on top of any DOS/Microsoft Windows system without partitioning your -+ hard disk. Unlike other Linux distributions TopologiLinux does not -+ need its own partition. For more information see -+ <http://topologi-linux.sourceforge.net/> -+ -+ It is perfectly safe to say N here. -+ -+endmenu -+endif # BLOCK -+ -+menu "Pseudo filesystems" -+ -+source "fs/proc/Kconfig" -+ -+config SYSFS -+ bool "sysfs file system support" if EMBEDDED -+ default y -+ help -+ The sysfs filesystem is a virtual filesystem that the kernel uses to -+ export internal kernel objects, their attributes, and their -+ relationships to one another. -+ -+ Users can use sysfs to ascertain useful information about the running -+ kernel, such as the devices the kernel has discovered on each bus and -+ which driver each is bound to. sysfs can also be used to tune devices -+ and other kernel subsystems. -+ -+ Some system agents rely on the information in sysfs to operate. -+ /sbin/hotplug uses device and object attributes in sysfs to assist in -+ delegating policy decisions, like persistently naming devices. -+ -+ sysfs is currently used by the block subsystem to mount the root -+ partition. If sysfs is disabled you must specify the boot device on -+ the kernel boot command line via its major and minor numbers. For -+ example, "root=03:01" for /dev/hda1. -+ -+ Designers of embedded systems may wish to say N here to conserve space. -+ -+config TMPFS -+ bool "Virtual memory file system support (former shm fs)" -+ help -+ Tmpfs is a file system which keeps all files in virtual memory. -+ -+ Everything in tmpfs is temporary in the sense that no files will be -+ created on your hard drive. The files live in memory and swap -+ space. If you unmount a tmpfs instance, everything stored therein is -+ lost. -+ -+ See <file:Documentation/filesystems/tmpfs.txt> for details. -+ -+config TMPFS_POSIX_ACL -+ bool "Tmpfs POSIX Access Control Lists" -+ depends on TMPFS -+ select GENERIC_ACL -+ help -+ POSIX Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the POSIX ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N. -+ -+config HUGETLBFS -+ bool "HugeTLB file system support" -+ depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \ -+ (S390 && 64BIT) || BROKEN -+ help -+ hugetlbfs is a filesystem backing for HugeTLB pages, based on -+ ramfs. For architectures that support it, say Y here and read -+ <file:Documentation/vm/hugetlbpage.txt> for details. -+ -+ If unsure, say N. -+ -+config HUGETLB_PAGE -+ def_bool HUGETLBFS -+ -+config CONFIGFS_FS -+ tristate "Userspace-driven configuration filesystem" -+ depends on SYSFS -+ help -+ configfs is a ram-based filesystem that provides the converse -+ of sysfs's functionality. Where sysfs is a filesystem-based -+ view of kernel objects, configfs is a filesystem-based manager -+ of kernel objects, or config_items. -+ -+ Both sysfs and configfs can and should exist together on the -+ same system. One is not a replacement for the other. -+ -+endmenu -+ -+menu "Miscellaneous filesystems" -+ -+config ADFS_FS -+ tristate "ADFS file system support (EXPERIMENTAL)" -+ depends on BLOCK && EXPERIMENTAL -+ help -+ The Acorn Disc Filing System is the standard file system of the -+ RiscOS operating system which runs on Acorn's ARM-based Risc PC -+ systems and the Acorn Archimedes range of machines. If you say Y -+ here, Linux will be able to read from ADFS partitions on hard drives -+ and from ADFS-formatted floppy discs. If you also want to be able to -+ write to those devices, say Y to "ADFS write support" below. -+ -+ The ADFS partition should be the first partition (i.e., -+ /dev/[hs]d?1) on each of your drives. Please read the file -+ <file:Documentation/filesystems/adfs.txt> for further details. -+ -+ To compile this code as a module, choose M here: the module will be -+ called adfs. -+ -+ If unsure, say N. -+ -+config ADFS_FS_RW -+ bool "ADFS write support (DANGEROUS)" -+ depends on ADFS_FS -+ help -+ If you say Y here, you will be able to write to ADFS partitions on -+ hard drives and ADFS-formatted floppy disks. This is experimental -+ codes, so if you're unsure, say N. -+ -+config AFFS_FS -+ tristate "Amiga FFS file system support (EXPERIMENTAL)" -+ depends on BLOCK && EXPERIMENTAL -+ help -+ The Fast File System (FFS) is the common file system used on hard -+ disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y -+ if you want to be able to read and write files from and to an Amiga -+ FFS partition on your hard drive. Amiga floppies however cannot be -+ read with this driver due to an incompatibility of the floppy -+ controller used in an Amiga and the standard floppy controller in -+ PCs and workstations. Read <file:Documentation/filesystems/affs.txt> -+ and <file:fs/affs/Changes>. -+ -+ With this driver you can also mount disk files used by Bernd -+ Schmidt's Un*X Amiga Emulator -+ (<http://www.freiburg.linux.de/~uae/>). -+ If you want to do this, you will also need to say Y or M to "Loop -+ device support", above. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called affs. If unsure, say N. -+ -+config ECRYPT_FS -+ tristate "eCrypt filesystem layer support (EXPERIMENTAL)" -+ depends on EXPERIMENTAL && KEYS && CRYPTO && NET -+ help -+ Encrypted filesystem that operates on the VFS layer. See -+ <file:Documentation/filesystems/ecryptfs.txt> to learn more about -+ eCryptfs. Userspace components are required and can be -+ obtained from <http://ecryptfs.sf.net>. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called ecryptfs. -+ -+config HFS_FS -+ tristate "Apple Macintosh file system support (EXPERIMENTAL)" -+ depends on BLOCK && EXPERIMENTAL -+ select NLS -+ help -+ If you say Y here, you will be able to mount Macintosh-formatted -+ floppy disks and hard drive partitions with full read-write access. -+ Please read <file:Documentation/filesystems/hfs.txt> to learn about -+ the available mount options. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called hfs. -+ -+config HFSPLUS_FS -+ tristate "Apple Extended HFS file system support" -+ depends on BLOCK -+ select NLS -+ select NLS_UTF8 -+ help -+ If you say Y here, you will be able to mount extended format -+ Macintosh-formatted hard drive partitions with full read-write access. -+ -+ This file system is often called HFS+ and was introduced with -+ MacOS 8. It includes all Mac specific filesystem data such as -+ data forks and creator codes, but it also has several UNIX -+ style features such as file ownership and permissions. -+ -+config BEFS_FS -+ tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)" -+ depends on BLOCK && EXPERIMENTAL -+ select NLS -+ help -+ The BeOS File System (BeFS) is the native file system of Be, Inc's -+ BeOS. Notable features include support for arbitrary attributes -+ on files and directories, and database-like indices on selected -+ attributes. (Also note that this driver doesn't make those features -+ available at this time). It is a 64 bit filesystem, so it supports -+ extremely large volumes and files. -+ -+ If you use this filesystem, you should also say Y to at least one -+ of the NLS (native language support) options below. -+ -+ If you don't know what this is about, say N. -+ -+ To compile this as a module, choose M here: the module will be -+ called befs. -+ -+config BEFS_DEBUG -+ bool "Debug BeFS" -+ depends on BEFS_FS -+ help -+ If you say Y here, you can use the 'debug' mount option to enable -+ debugging output from the driver. -+ -+config BFS_FS -+ tristate "BFS file system support (EXPERIMENTAL)" -+ depends on BLOCK && EXPERIMENTAL -+ help -+ Boot File System (BFS) is a file system used under SCO UnixWare to -+ allow the bootloader access to the kernel image and other important -+ files during the boot process. It is usually mounted under /stand -+ and corresponds to the slice marked as "STAND" in the UnixWare -+ partition. You should say Y if you want to read or write the files -+ on your /stand slice from within Linux. You then also need to say Y -+ to "UnixWare slices support", below. More information about the BFS -+ file system is contained in the file -+ <file:Documentation/filesystems/bfs.txt>. -+ -+ If you don't know what this is about, say N. -+ -+ To compile this as a module, choose M here: the module will be called -+ bfs. Note that the file system of your root partition (the one -+ containing the directory /) cannot be compiled as a module. -+ -+ -+ -+config EFS_FS -+ tristate "EFS file system support (read only) (EXPERIMENTAL)" -+ depends on BLOCK && EXPERIMENTAL -+ help -+ EFS is an older file system used for non-ISO9660 CD-ROMs and hard -+ disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer -+ uses the XFS file system for hard disk partitions however). -+ -+ This implementation only offers read-only access. If you don't know -+ what all this is about, it's safe to say N. For more information -+ about EFS see its home page at <http://aeschi.ch.eu.org/efs/>. -+ -+ To compile the EFS file system support as a module, choose M here: the -+ module will be called efs. -+ -+config JFFS2_FS -+ tristate "Journalling Flash File System v2 (JFFS2) support" -+ select CRC32 -+ depends on MTD -+ help -+ JFFS2 is the second generation of the Journalling Flash File System -+ for use on diskless embedded devices. It provides improved wear -+ levelling, compression and support for hard links. You cannot use -+ this on normal block devices, only on 'MTD' devices. -+ -+ Further information on the design and implementation of JFFS2 is -+ available at <http://sources.redhat.com/jffs2/>. -+ -+config JFFS2_FS_DEBUG -+ int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)" -+ depends on JFFS2_FS -+ default "0" -+ help -+ This controls the amount of debugging messages produced by the JFFS2 -+ code. Set it to zero for use in production systems. For evaluation, -+ testing and debugging, it's advisable to set it to one. This will -+ enable a few assertions and will print debugging messages at the -+ KERN_DEBUG loglevel, where they won't normally be visible. Level 2 -+ is unlikely to be useful - it enables extra debugging in certain -+ areas which at one point needed debugging, but when the bugs were -+ located and fixed, the detailed messages were relegated to level 2. -+ -+ If reporting bugs, please try to have available a full dump of the -+ messages at debug level 1 while the misbehaviour was occurring. -+ -+config JFFS2_FS_WRITEBUFFER -+ bool "JFFS2 write-buffering support" -+ depends on JFFS2_FS -+ default y -+ help -+ This enables the write-buffering support in JFFS2. -+ -+ This functionality is required to support JFFS2 on the following -+ types of flash devices: -+ - NAND flash -+ - NOR flash with transparent ECC -+ - DataFlash -+ -+config JFFS2_FS_WBUF_VERIFY -+ bool "Verify JFFS2 write-buffer reads" -+ depends on JFFS2_FS_WRITEBUFFER -+ default n -+ help -+ This causes JFFS2 to read back every page written through the -+ write-buffer, and check for errors. -+ -+config JFFS2_SUMMARY -+ bool "JFFS2 summary support (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default n -+ help -+ This feature makes it possible to use summary information -+ for faster filesystem mount. -+ -+ The summary information can be inserted into a filesystem image -+ by the utility 'sumtool'. -+ -+ If unsure, say 'N'. -+ -+config JFFS2_FS_XATTR -+ bool "JFFS2 XATTR support (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default n -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ <http://acl.bestbits.at/> for details). -+ -+ If unsure, say N. -+ -+config JFFS2_FS_POSIX_ACL -+ bool "JFFS2 POSIX Access Control Lists" -+ depends on JFFS2_FS_XATTR -+ default y -+ select FS_POSIX_ACL -+ help -+ Posix Access Control Lists (ACLs) support permissions for users and -+ groups beyond the owner/group/world scheme. -+ -+ To learn more about Access Control Lists, visit the Posix ACLs for -+ Linux website <http://acl.bestbits.at/>. -+ -+ If you don't know what Access Control Lists are, say N -+ -+config JFFS2_FS_SECURITY -+ bool "JFFS2 Security Labels" -+ depends on JFFS2_FS_XATTR -+ default y -+ help -+ Security labels support alternative access control models -+ implemented by security modules like SELinux. This option -+ enables an extended attribute handler for file security -+ labels in the jffs2 filesystem. -+ -+ If you are not using a security module that requires using -+ extended attributes for file security labels, say N. -+ -+config JFFS2_COMPRESSION_OPTIONS -+ bool "Advanced compression options for JFFS2" -+ depends on JFFS2_FS -+ default n -+ help -+ Enabling this option allows you to explicitly choose which -+ compression modules, if any, are enabled in JFFS2. Removing -+ compressors can mean you cannot read existing file systems, -+ and enabling experimental compressors can mean that you -+ write a file system which cannot be read by a standard kernel. -+ -+ If unsure, you should _definitely_ say 'N'. -+ -+config JFFS2_ZLIB -+ bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS -+ select ZLIB_INFLATE -+ select ZLIB_DEFLATE -+ depends on JFFS2_FS -+ default y -+ help -+ Zlib is designed to be a free, general-purpose, legally unencumbered, -+ lossless data-compression library for use on virtually any computer -+ hardware and operating system. See <http://www.gzip.org/zlib/> for -+ further information. -+ -+ Say 'Y' if unsure. -+ -+config JFFS2_LZO -+ bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS -+ select LZO_COMPRESS -+ select LZO_DECOMPRESS -+ depends on JFFS2_FS -+ default n -+ help -+ minilzo-based compression. Generally works better than Zlib. -+ -+ This feature was added in July, 2007. Say 'N' if you need -+ compatibility with older bootloaders or kernels. -+ -+config JFFS2_RTIME -+ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS -+ depends on JFFS2_FS -+ default y -+ help -+ Rtime does manage to recompress already-compressed data. Say 'Y' if unsure. -+ -+config JFFS2_RUBIN -+ bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS -+ depends on JFFS2_FS -+ default n -+ help -+ RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure. -+ -+choice -+ prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS -+ default JFFS2_CMODE_PRIORITY -+ depends on JFFS2_FS -+ help -+ You can set here the default compression mode of JFFS2 from -+ the available compression modes. Don't touch if unsure. -+ -+config JFFS2_CMODE_NONE -+ bool "no compression" -+ help -+ Uses no compression. -+ -+config JFFS2_CMODE_PRIORITY -+ bool "priority" -+ help -+ Tries the compressors in a predefined order and chooses the first -+ successful one. -+ -+config JFFS2_CMODE_SIZE -+ bool "size (EXPERIMENTAL)" -+ help -+ Tries all compressors and chooses the one which has the smallest -+ result. -+ -+config JFFS2_CMODE_FAVOURLZO -+ bool "Favour LZO" -+ help -+ Tries all compressors and chooses the one which has the smallest -+ result but gives some preference to LZO (which has faster -+ decompression) at the expense of size. -+ -+endchoice -+ -+# UBIFS File system configuration -+source "fs/ubifs/Kconfig" -+ -+config CRAMFS -+ tristate "Compressed ROM file system support (cramfs)" -+ depends on BLOCK -+ select ZLIB_INFLATE -+ help -+ Saying Y here includes support for CramFs (Compressed ROM File -+ System). CramFs is designed to be a simple, small, and compressed -+ file system for ROM based embedded systems. CramFs is read-only, -+ limited to 256MB file systems (with 16MB files), and doesn't support -+ 16/32 bits uid/gid, hard links and timestamps. -+ -+ See <file:Documentation/filesystems/cramfs.txt> and -+ <file:fs/cramfs/README> for further information. -+ -+ To compile this as a module, choose M here: the module will be called -+ cramfs. Note that the root file system (the one containing the -+ directory /) cannot be compiled as a module. -+ -+ If unsure, say N. -+ -+config VXFS_FS -+ tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" -+ depends on BLOCK -+ help -+ FreeVxFS is a file system driver that support the VERITAS VxFS(TM) -+ file system format. VERITAS VxFS(TM) is the standard file system -+ of SCO UnixWare (and possibly others) and optionally available -+ for Sunsoft Solaris, HP-UX and many other operating systems. -+ Currently only readonly access is supported. -+ -+ NOTE: the file system type as used by mount(1), mount(2) and -+ fstab(5) is 'vxfs' as it describes the file system format, not -+ the actual driver. -+ -+ To compile this as a module, choose M here: the module will be -+ called freevxfs. If unsure, say N. -+ -+config MINIX_FS -+ tristate "Minix file system support" -+ depends on BLOCK -+ help -+ Minix is a simple operating system used in many classes about OS's. -+ The minix file system (method to organize files on a hard disk -+ partition or a floppy disk) was the original file system for Linux, -+ but has been superseded by the second extended file system ext2fs. -+ You don't want to use the minix file system on your hard disk -+ because of certain built-in restrictions, but it is sometimes found -+ on older Linux floppy disks. This option will enlarge your kernel -+ by about 28 KB. If unsure, say N. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called minix. Note that the file system of your root -+ partition (the one containing the directory /) cannot be compiled as -+ a module. -+ -+config OMFS_FS -+ tristate "SonicBlue Optimized MPEG File System support" -+ depends on BLOCK -+ select CRC_ITU_T -+ help -+ This is the proprietary file system used by the Rio Karma music -+ player and ReplayTV DVR. Despite the name, this filesystem is not -+ more efficient than a standard FS for MPEG files, in fact likely -+ the opposite is true. Say Y if you have either of these devices -+ and wish to mount its disk. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called omfs. If unsure, say N. -+ -+config HPFS_FS -+ tristate "OS/2 HPFS file system support" -+ depends on BLOCK -+ help -+ OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS -+ is the file system used for organizing files on OS/2 hard disk -+ partitions. Say Y if you want to be able to read files from and -+ write files to an OS/2 HPFS partition on your hard drive. OS/2 -+ floppies however are in regular MSDOS format, so you don't need this -+ option in order to be able to read them. Read -+ <file:Documentation/filesystems/hpfs.txt>. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called hpfs. If unsure, say N. -+ -+ -+config QNX4FS_FS -+ tristate "QNX4 file system support (read only)" -+ depends on BLOCK -+ help -+ This is the file system used by the real-time operating systems -+ QNX 4 and QNX 6 (the latter is also called QNX RTP). -+ Further information is available at <http://www.qnx.com/>. -+ Say Y if you intend to mount QNX hard disks or floppies. -+ Unless you say Y to "QNX4FS read-write support" below, you will -+ only be able to read these file systems. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called qnx4. -+ -+ If you don't know whether you need it, then you don't need it: -+ answer N. -+ -+config QNX4FS_RW -+ bool "QNX4FS write support (DANGEROUS)" -+ depends on QNX4FS_FS && EXPERIMENTAL && BROKEN -+ help -+ Say Y if you want to test write support for QNX4 file systems. -+ -+ It's currently broken, so for now: -+ answer N. -+ -+config ROMFS_FS -+ tristate "ROM file system support" -+ depends on BLOCK -+ ---help--- -+ This is a very small read-only file system mainly intended for -+ initial ram disks of installation disks, but it could be used for -+ other read-only media as well. Read -+ <file:Documentation/filesystems/romfs.txt> for details. -+ -+ To compile this file system support as a module, choose M here: the -+ module will be called romfs. Note that the file system of your -+ root partition (the one containing the directory /) cannot be a -+ module. -+ -+ If you don't know whether you need it, then you don't need it: -+ answer N. -+ -+ -+config SYSV_FS -+ tristate "System V/Xenix/V7/Coherent file system support" -+ depends on BLOCK -+ help -+ SCO, Xenix and Coherent are commercial Unix systems for Intel -+ machines, and Version 7 was used on the DEC PDP-11. Saying Y -+ here would allow you to read from their floppies and hard disk -+ partitions. -+ -+ If you have floppies or hard disk partitions like that, it is likely -+ that they contain binaries from those other Unix systems; in order -+ to run these binaries, you will want to install linux-abi which is -+ a set of kernel modules that lets you run SCO, Xenix, Wyse, -+ UnixWare, Dell Unix and System V programs under Linux. It is -+ available via FTP (user: ftp) from -+ <ftp://ftp.openlinux.org/pub/people/hch/linux-abi/>). -+ NOTE: that will work only for binaries from Intel-based systems; -+ PDP ones will have to wait until somebody ports Linux to -11 ;-) -+ -+ If you only intend to mount files from some other Unix over the -+ network using NFS, you don't need the System V file system support -+ (but you need NFS file system support obviously). -+ -+ Note that this option is generally not needed for floppies, since a -+ good portable way to transport files and directories between unixes -+ (and even other operating systems) is given by the tar program ("man -+ tar" or preferably "info tar"). Note also that this option has -+ nothing whatsoever to do with the option "System V IPC". Read about -+ the System V file system in -+ <file:Documentation/filesystems/sysv-fs.txt>. -+ Saying Y here will enlarge your kernel by about 27 KB. -+ -+ To compile this as a module, choose M here: the module will be called -+ sysv. -+ -+ If you haven't heard about all of this before, it's safe to say N. -+ -+ -+config UFS_FS -+ tristate "UFS file system support (read only)" -+ depends on BLOCK -+ help -+ BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, -+ OpenBSD and NeXTstep) use a file system called UFS. Some System V -+ Unixes can create and mount hard disk partitions and diskettes using -+ this file system as well. Saying Y here will allow you to read from -+ these partitions; if you also want to write to them, say Y to the -+ experimental "UFS file system write support", below. Please read the -+ file <file:Documentation/filesystems/ufs.txt> for more information. -+ -+ The recently released UFS2 variant (used in FreeBSD 5.x) is -+ READ-ONLY supported. -+ -+ Note that this option is generally not needed for floppies, since a -+ good portable way to transport files and directories between unixes -+ (and even other operating systems) is given by the tar program ("man -+ tar" or preferably "info tar"). -+ -+ When accessing NeXTstep files, you may need to convert them from the -+ NeXT character set to the Latin1 character set; use the program -+ recode ("info recode") for this purpose. -+ -+ To compile the UFS file system support as a module, choose M here: the -+ module will be called ufs. -+ -+ If you haven't heard about all of this before, it's safe to say N. -+ -+config UFS_FS_WRITE -+ bool "UFS file system write support (DANGEROUS)" -+ depends on UFS_FS && EXPERIMENTAL -+ help -+ Say Y here if you want to try writing to UFS partitions. This is -+ experimental, so you should back up your UFS partitions beforehand. -+ -+config UFS_DEBUG -+ bool "UFS debugging" -+ depends on UFS_FS -+ help -+ If you are experiencing any problems with the UFS filesystem, say -+ Y here. This will result in _many_ additional debugging messages to be -+ written to the system log. -+ -+endmenu -+ -+menuconfig NETWORK_FILESYSTEMS -+ bool "Network File Systems" -+ default y -+ depends on NET -+ ---help--- -+ Say Y here to get to see options for network filesystems and -+ filesystem-related networking code, such as NFS daemon and -+ RPCSEC security modules. -+ -+ This option alone does not add any kernel code. -+ -+ If you say N, all options in this submenu will be skipped and -+ disabled; if unsure, say Y here. -+ -+if NETWORK_FILESYSTEMS -+ -+config NFS_FS -+ tristate "NFS client support" -+ depends on INET -+ select LOCKD -+ select SUNRPC -+ select NFS_ACL_SUPPORT if NFS_V3_ACL -+ help -+ Choose Y here if you want to access files residing on other -+ computers using Sun's Network File System protocol. To compile -+ this file system support as a module, choose M here: the module -+ will be called nfs. -+ -+ To mount file systems exported by NFS servers, you also need to -+ install the user space mount.nfs command which can be found in -+ the Linux nfs-utils package, available from http://linux-nfs.org/. -+ Information about using the mount command is available in the -+ mount(8) man page. More detail about the Linux NFS client -+ implementation is available via the nfs(5) man page. -+ -+ Below you can choose which versions of the NFS protocol are -+ available in the kernel to mount NFS servers. Support for NFS -+ version 2 (RFC 1094) is always available when NFS_FS is selected. -+ -+ To configure a system which mounts its root file system via NFS -+ at boot time, say Y here, select "Kernel level IP -+ autoconfiguration" in the NETWORK menu, and select "Root file -+ system on NFS" below. You cannot compile this file system as a -+ module in this case. -+ -+ If unsure, say N. -+ -+config NFS_V3 -+ bool "NFS client support for NFS version 3" -+ depends on NFS_FS -+ help -+ This option enables support for version 3 of the NFS protocol -+ (RFC 1813) in the kernel's NFS client. -+ -+ If unsure, say Y. -+ -+config NFS_V3_ACL -+ bool "NFS client support for the NFSv3 ACL protocol extension" -+ depends on NFS_V3 -+ help -+ Some NFS servers support an auxiliary NFSv3 ACL protocol that -+ Sun added to Solaris but never became an official part of the -+ NFS version 3 protocol. This protocol extension allows -+ applications on NFS clients to manipulate POSIX Access Control -+ Lists on files residing on NFS servers. NFS servers enforce -+ ACLs on local files whether this protocol is available or not. -+ -+ Choose Y here if your NFS server supports the Solaris NFSv3 ACL -+ protocol extension and you want your NFS client to allow -+ applications to access and modify ACLs on files on the server. -+ -+ Most NFS servers don't support the Solaris NFSv3 ACL protocol -+ extension. You can choose N here or specify the "noacl" mount -+ option to prevent your NFS client from trying to use the NFSv3 -+ ACL protocol. -+ -+ If unsure, say N. -+ -+config NFS_V4 -+ bool "NFS client support for NFS version 4 (EXPERIMENTAL)" -+ depends on NFS_FS && EXPERIMENTAL -+ select RPCSEC_GSS_KRB5 -+ help -+ This option enables support for version 4 of the NFS protocol -+ (RFC 3530) in the kernel's NFS client. -+ -+ To mount NFS servers using NFSv4, you also need to install user -+ space programs which can be found in the Linux nfs-utils package, -+ available from http://linux-nfs.org/. -+ -+ If unsure, say N. -+ -+config ROOT_NFS -+ bool "Root file system on NFS" -+ depends on NFS_FS=y && IP_PNP -+ help -+ If you want your system to mount its root file system via NFS, -+ choose Y here. This is common practice for managing systems -+ without local permanent storage. For details, read -+ <file:Documentation/filesystems/nfsroot.txt>. -+ -+ Most people say N here. -+ -+config NFSD -+ tristate "NFS server support" -+ depends on INET -+ select LOCKD -+ select SUNRPC -+ select EXPORTFS -+ select NFS_ACL_SUPPORT if NFSD_V2_ACL -+ help -+ Choose Y here if you want to allow other computers to access -+ files residing on this system using Sun's Network File System -+ protocol. To compile the NFS server support as a module, -+ choose M here: the module will be called nfsd. -+ -+ You may choose to use a user-space NFS server instead, in which -+ case you can choose N here. -+ -+ To export local file systems using NFS, you also need to install -+ user space programs which can be found in the Linux nfs-utils -+ package, available from http://linux-nfs.org/. More detail about -+ the Linux NFS server implementation is available via the -+ exports(5) man page. -+ -+ Below you can choose which versions of the NFS protocol are -+ available to clients mounting the NFS server on this system. -+ Support for NFS version 2 (RFC 1094) is always available when -+ CONFIG_NFSD is selected. -+ -+ If unsure, say N. -+ -+config NFSD_V2_ACL -+ bool -+ depends on NFSD -+ -+config NFSD_V3 -+ bool "NFS server support for NFS version 3" -+ depends on NFSD -+ help -+ This option enables support in your system's NFS server for -+ version 3 of the NFS protocol (RFC 1813). -+ -+ If unsure, say Y. -+ -+config NFSD_V3_ACL -+ bool "NFS server support for the NFSv3 ACL protocol extension" -+ depends on NFSD_V3 -+ select NFSD_V2_ACL -+ help -+ Solaris NFS servers support an auxiliary NFSv3 ACL protocol that -+ never became an official part of the NFS version 3 protocol. -+ This protocol extension allows applications on NFS clients to -+ manipulate POSIX Access Control Lists on files residing on NFS -+ servers. NFS servers enforce POSIX ACLs on local files whether -+ this protocol is available or not. -+ -+ This option enables support in your system's NFS server for the -+ NFSv3 ACL protocol extension allowing NFS clients to manipulate -+ POSIX ACLs on files exported by your system's NFS server. NFS -+ clients which support the Solaris NFSv3 ACL protocol can then -+ access and modify ACLs on your NFS server. -+ -+ To store ACLs on your NFS server, you also need to enable ACL- -+ related CONFIG options for your local file systems of choice. -+ -+ If unsure, say N. -+ -+config NFSD_V4 -+ bool "NFS server support for NFS version 4 (EXPERIMENTAL)" -+ depends on NFSD && PROC_FS && EXPERIMENTAL -+ select NFSD_V3 -+ select FS_POSIX_ACL -+ select RPCSEC_GSS_KRB5 -+ help -+ This option enables support in your system's NFS server for -+ version 4 of the NFS protocol (RFC 3530). -+ -+ To export files using NFSv4, you need to install additional user -+ space programs which can be found in the Linux nfs-utils package, -+ available from http://linux-nfs.org/. -+ -+ If unsure, say N. -+ -+config LOCKD -+ tristate -+ -+config LOCKD_V4 -+ bool -+ depends on NFSD_V3 || NFS_V3 -+ default y -+ -+config EXPORTFS -+ tristate -+ -+config NFS_ACL_SUPPORT -+ tristate -+ select FS_POSIX_ACL -+ -+config NFS_COMMON -+ bool -+ depends on NFSD || NFS_FS -+ default y -+ -+config SUNRPC -+ tristate -+ -+config SUNRPC_GSS -+ tristate -+ -+config SUNRPC_XPRT_RDMA -+ tristate -+ depends on SUNRPC && INFINIBAND && EXPERIMENTAL -+ default SUNRPC && INFINIBAND -+ help -+ This option enables an RPC client transport capability that -+ allows the NFS client to mount servers via an RDMA-enabled -+ transport. -+ -+ To compile RPC client RDMA transport support as a module, -+ choose M here: the module will be called xprtrdma. -+ -+ If unsure, say N. -+ -+config RPCSEC_GSS_KRB5 -+ tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" -+ depends on SUNRPC && EXPERIMENTAL -+ select SUNRPC_GSS -+ select CRYPTO -+ select CRYPTO_MD5 -+ select CRYPTO_DES -+ select CRYPTO_CBC -+ help -+ Choose Y here to enable Secure RPC using the Kerberos version 5 -+ GSS-API mechanism (RFC 1964). -+ -+ Secure RPC calls with Kerberos require an auxiliary user-space -+ daemon which may be found in the Linux nfs-utils package -+ available from http://linux-nfs.org/. In addition, user-space -+ Kerberos support should be installed. -+ -+ If unsure, say N. -+ -+config RPCSEC_GSS_SPKM3 -+ tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)" -+ depends on SUNRPC && EXPERIMENTAL -+ select SUNRPC_GSS -+ select CRYPTO -+ select CRYPTO_MD5 -+ select CRYPTO_DES -+ select CRYPTO_CAST5 -+ select CRYPTO_CBC -+ help -+ Choose Y here to enable Secure RPC using the SPKM3 public key -+ GSS-API mechansim (RFC 2025). -+ -+ Secure RPC calls with SPKM3 require an auxiliary userspace -+ daemon which may be found in the Linux nfs-utils package -+ available from http://linux-nfs.org/. -+ -+ If unsure, say N. -+ -+config SMB_FS -+ tristate "SMB file system support (OBSOLETE, please use CIFS)" -+ depends on INET -+ select NLS -+ help -+ SMB (Server Message Block) is the protocol Windows for Workgroups -+ (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share -+ files and printers over local networks. Saying Y here allows you to -+ mount their file systems (often called "shares" in this context) and -+ access them just like any other Unix directory. Currently, this -+ works only if the Windows machines use TCP/IP as the underlying -+ transport protocol, and not NetBEUI. For details, read -+ <file:Documentation/filesystems/smbfs.txt> and the SMB-HOWTO, -+ available from <http://www.tldp.org/docs.html#howto>. -+ -+ Note: if you just want your box to act as an SMB *server* and make -+ files and printing services available to Windows clients (which need -+ to have a TCP/IP stack), you don't need to say Y here; you can use -+ the program SAMBA (available from <ftp://ftp.samba.org/pub/samba/>) -+ for that. -+ -+ General information about how to connect Linux, Windows machines and -+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. -+ -+ To compile the SMB support as a module, choose M here: -+ the module will be called smbfs. Most people say N, however. -+ -+config SMB_NLS_DEFAULT -+ bool "Use a default NLS" -+ depends on SMB_FS -+ help -+ Enabling this will make smbfs use nls translations by default. You -+ need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls -+ settings and you need to give the default nls for the SMB server as -+ CONFIG_SMB_NLS_REMOTE. -+ -+ The nls settings can be changed at mount time, if your smbmount -+ supports that, using the codepage and iocharset parameters. -+ -+ smbmount from samba 2.2.0 or later supports this. -+ -+config SMB_NLS_REMOTE -+ string "Default Remote NLS Option" -+ depends on SMB_NLS_DEFAULT -+ default "cp437" -+ help -+ This setting allows you to specify a default value for which -+ codepage the server uses. If this field is left blank no -+ translations will be done by default. The local codepage/charset -+ default to CONFIG_NLS_DEFAULT. -+ -+ The nls settings can be changed at mount time, if your smbmount -+ supports that, using the codepage and iocharset parameters. -+ -+ smbmount from samba 2.2.0 or later supports this. -+ -+config CIFS -+ tristate "CIFS support (advanced network filesystem, SMBFS successor)" -+ depends on INET -+ select NLS -+ help -+ This is the client VFS module for the Common Internet File System -+ (CIFS) protocol which is the successor to the Server Message Block -+ (SMB) protocol, the native file sharing mechanism for most early -+ PC operating systems. The CIFS protocol is fully supported by -+ file servers such as Windows 2000 (including Windows 2003, NT 4 -+ and Windows XP) as well by Samba (which provides excellent CIFS -+ server support for Linux and many other operating systems). Limited -+ support for OS/2 and Windows ME and similar servers is provided as -+ well. -+ -+ The cifs module provides an advanced network file system -+ client for mounting to CIFS compliant servers. It includes -+ support for DFS (hierarchical name space), secure per-user -+ session establishment via Kerberos or NTLM or NTLMv2, -+ safe distributed caching (oplock), optional packet -+ signing, Unicode and other internationalization improvements. -+ If you need to mount to Samba or Windows from this machine, say Y. -+ -+config CIFS_STATS -+ bool "CIFS statistics" -+ depends on CIFS -+ help -+ Enabling this option will cause statistics for each server share -+ mounted by the cifs client to be displayed in /proc/fs/cifs/Stats -+ -+config CIFS_STATS2 -+ bool "Extended statistics" -+ depends on CIFS_STATS -+ help -+ Enabling this option will allow more detailed statistics on SMB -+ request timing to be displayed in /proc/fs/cifs/DebugData and also -+ allow optional logging of slow responses to dmesg (depending on the -+ value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details). -+ These additional statistics may have a minor effect on performance -+ and memory utilization. -+ -+ Unless you are a developer or are doing network performance analysis -+ or tuning, say N. -+ -+config CIFS_WEAK_PW_HASH -+ bool "Support legacy servers which use weaker LANMAN security" -+ depends on CIFS -+ help -+ Modern CIFS servers including Samba and most Windows versions -+ (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos) -+ security mechanisms. These hash the password more securely -+ than the mechanisms used in the older LANMAN version of the -+ SMB protocol but LANMAN based authentication is needed to -+ establish sessions with some old SMB servers. -+ -+ Enabling this option allows the cifs module to mount to older -+ LANMAN based servers such as OS/2 and Windows 95, but such -+ mounts may be less secure than mounts using NTLM or more recent -+ security mechanisms if you are on a public network. Unless you -+ have a need to access old SMB servers (and are on a private -+ network) you probably want to say N. Even if this support -+ is enabled in the kernel build, LANMAN authentication will not be -+ used automatically. At runtime LANMAN mounts are disabled but -+ can be set to required (or optional) either in -+ /proc/fs/cifs (see fs/cifs/README for more detail) or via an -+ option on the mount command. This support is disabled by -+ default in order to reduce the possibility of a downgrade -+ attack. -+ -+ If unsure, say N. -+ -+config CIFS_XATTR -+ bool "CIFS extended attributes" -+ depends on CIFS -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ <http://acl.bestbits.at/> for details). CIFS maps the name of -+ extended attributes beginning with the user namespace prefix -+ to SMB/CIFS EAs. EAs are stored on Windows servers without the -+ user namespace prefix, but their names are seen by Linux cifs clients -+ prefaced by the user namespace prefix. The system namespace -+ (used by some filesystems to store ACLs) is not supported at -+ this time. -+ -+ If unsure, say N. -+ -+config CIFS_POSIX -+ bool "CIFS POSIX Extensions" -+ depends on CIFS_XATTR -+ help -+ Enabling this option will cause the cifs client to attempt to -+ negotiate a newer dialect with servers, such as Samba 3.0.5 -+ or later, that optionally can handle more POSIX like (rather -+ than Windows like) file behavior. It also enables -+ support for POSIX ACLs (getfacl and setfacl) to servers -+ (such as Samba 3.10 and later) which can negotiate -+ CIFS POSIX ACL support. If unsure, say N. -+ -+config CIFS_DEBUG2 -+ bool "Enable additional CIFS debugging routines" -+ depends on CIFS -+ help -+ Enabling this option adds a few more debugging routines -+ to the cifs code which slightly increases the size of -+ the cifs module and can cause additional logging of debug -+ messages in some error paths, slowing performance. This -+ option can be turned off unless you are debugging -+ cifs problems. If unsure, say N. -+ -+config CIFS_EXPERIMENTAL -+ bool "CIFS Experimental Features (EXPERIMENTAL)" -+ depends on CIFS && EXPERIMENTAL -+ help -+ Enables cifs features under testing. These features are -+ experimental and currently include DFS support and directory -+ change notification ie fcntl(F_DNOTIFY), as well as the upcall -+ mechanism which will be used for Kerberos session negotiation -+ and uid remapping. Some of these features also may depend on -+ setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental -+ (which is disabled by default). See the file fs/cifs/README -+ for more details. If unsure, say N. -+ -+config CIFS_UPCALL -+ bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" -+ depends on CIFS_EXPERIMENTAL -+ depends on KEYS -+ help -+ Enables an upcall mechanism for CIFS which accesses -+ userspace helper utilities to provide SPNEGO packaged (RFC 4178) -+ Kerberos tickets which are needed to mount to certain secure servers -+ (for which more secure Kerberos authentication is required). If -+ unsure, say N. -+ -+config CIFS_DFS_UPCALL -+ bool "DFS feature support (EXPERIMENTAL)" -+ depends on CIFS_EXPERIMENTAL -+ depends on KEYS -+ help -+ Enables an upcall mechanism for CIFS which contacts userspace -+ helper utilities to provide server name resolution (host names to -+ IP addresses) which is needed for implicit mounts of DFS junction -+ points. If unsure, say N. -+ -+config NCP_FS -+ tristate "NCP file system support (to mount NetWare volumes)" -+ depends on IPX!=n || INET -+ help -+ NCP (NetWare Core Protocol) is a protocol that runs over IPX and is -+ used by Novell NetWare clients to talk to file servers. It is to -+ IPX what NFS is to TCP/IP, if that helps. Saying Y here allows you -+ to mount NetWare file server volumes and to access them just like -+ any other Unix directory. For details, please read the file -+ <file:Documentation/filesystems/ncpfs.txt> in the kernel source and -+ the IPX-HOWTO from <http://www.tldp.org/docs.html#howto>. -+ -+ You do not have to say Y here if you want your Linux box to act as a -+ file *server* for Novell NetWare clients. -+ -+ General information about how to connect Linux, Windows machines and -+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. -+ -+ To compile this as a module, choose M here: the module will be called -+ ncpfs. Say N unless you are connected to a Novell network. -+ -+source "fs/ncpfs/Kconfig" -+ -+config CODA_FS -+ tristate "Coda file system support (advanced network fs)" -+ depends on INET -+ help -+ Coda is an advanced network file system, similar to NFS in that it -+ enables you to mount file systems of a remote server and access them -+ with regular Unix commands as if they were sitting on your hard -+ disk. Coda has several advantages over NFS: support for -+ disconnected operation (e.g. for laptops), read/write server -+ replication, security model for authentication and encryption, -+ persistent client caches and write back caching. -+ -+ If you say Y here, your Linux box will be able to act as a Coda -+ *client*. You will need user level code as well, both for the -+ client and server. Servers are currently user level, i.e. they need -+ no kernel support. Please read -+ <file:Documentation/filesystems/coda.txt> and check out the Coda -+ home page <http://www.coda.cs.cmu.edu/>. -+ -+ To compile the coda client support as a module, choose M here: the -+ module will be called coda. -+ -+config AFS_FS -+ tristate "Andrew File System support (AFS) (EXPERIMENTAL)" -+ depends on INET && EXPERIMENTAL -+ select AF_RXRPC -+ help -+ If you say Y here, you will get an experimental Andrew File System -+ driver. It currently only supports unsecured read-only AFS access. -+ -+ See <file:Documentation/filesystems/afs.txt> for more information. -+ -+ If unsure, say N. -+ -+config AFS_DEBUG -+ bool "AFS dynamic debugging" -+ depends on AFS_FS -+ help -+ Say Y here to make runtime controllable debugging messages appear. -+ -+ See <file:Documentation/filesystems/afs.txt> for more information. -+ -+ If unsure, say N. -+ -+config 9P_FS -+ tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" -+ depends on INET && NET_9P && EXPERIMENTAL -+ help -+ If you say Y here, you will get experimental support for -+ Plan 9 resource sharing via the 9P2000 protocol. -+ -+ See <http://v9fs.sf.net> for more information. -+ -+ If unsure, say N. -+ -+endif # NETWORK_FILESYSTEMS -+ -+if BLOCK -+menu "Partition Types" -+ -+source "fs/partitions/Kconfig" -+ -+endmenu -+endif -+ -+source "fs/nls/Kconfig" -+source "fs/dlm/Kconfig" -+ -+endmenu -diff -uNr a/fs/Makefile b/fs/Makefile ---- a/fs/Makefile 2008-07-28 19:40:31.000000000 -0700 -+++ b/fs/Makefile 2008-08-13 16:18:09.000000000 -0700 -@@ -74,6 +74,7 @@ - obj-$(CONFIG_JBD2) += jbd2/ - obj-$(CONFIG_EXT2_FS) += ext2/ - obj-$(CONFIG_CRAMFS) += cramfs/ -+obj-$(CONFIG_SQUASHFS) += squashfs/ - obj-y += ramfs/ - obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ - obj-$(CONFIG_CODA_FS) += coda/ -diff -uNr a/fs/squashfs/block.c b/fs/squashfs/block.c ---- a/fs/squashfs/block.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/block.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,314 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * block.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+static struct buffer_head *get_block_length(struct super_block *s, -+ int *cur_index, int *offset, int *c_byte) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ unsigned short temp; -+ struct buffer_head *bh; -+ -+ if (!(bh = sb_bread(s, *cur_index))) -+ goto out; -+ -+ if (msblk->devblksize - *offset == 1) { -+ if (msblk->swap) -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ else -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ brelse(bh); -+ if (!(bh = sb_bread(s, ++(*cur_index)))) -+ goto out; -+ if (msblk->swap) -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ bh->b_data); -+ else -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ bh->b_data); -+ *c_byte = temp; -+ *offset = 1; -+ } else { -+ if (msblk->swap) { -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ (bh->b_data + *offset + 1)); -+ } else { -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ (bh->b_data + *offset + 1)); -+ } -+ *c_byte = temp; -+ *offset += 2; -+ } -+ -+ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) { -+ if (*offset == msblk->devblksize) { -+ brelse(bh); -+ if (!(bh = sb_bread(s, ++(*cur_index)))) -+ goto out; -+ *offset = 0; -+ } -+ if (*((unsigned char *) (bh->b_data + *offset)) != -+ SQUASHFS_MARKER_BYTE) { -+ ERROR("Metadata block marker corrupt @ %x\n", -+ *cur_index); -+ brelse(bh); -+ goto out; -+ } -+ (*offset)++; -+ } -+ return bh; -+ -+out: -+ return NULL; -+} -+ -+ -+unsigned int squashfs_read_data(struct super_block *s, char *buffer, -+ long long index, unsigned int length, -+ long long *next_index, int srclength) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ struct buffer_head **bh; -+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1); -+ unsigned int cur_index = index >> msblk->devblksize_log2; -+ int bytes, avail_bytes, b = 0, k = 0; -+ unsigned int compressed; -+ unsigned int c_byte = length; -+ -+ bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) * -+ sizeof(struct buffer_head *), GFP_KERNEL); -+ if (bh == NULL) -+ goto read_failure; -+ -+ if (c_byte) { -+ bytes = -offset; -+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte); -+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); -+ -+ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, -+ compressed ? "" : "un", (unsigned int) c_byte, srclength); -+ -+ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) -+ goto read_failure; -+ -+ for (b = 0; bytes < (int) c_byte; b++, cur_index++) { -+ bh[b] = sb_getblk(s, cur_index); -+ if (bh[b] == NULL) -+ goto block_release; -+ bytes += msblk->devblksize; -+ } -+ ll_rw_block(READ, b, bh); -+ } else { -+ if (index < 0 || (index + 2) > sblk->bytes_used) -+ goto read_failure; -+ -+ bh[0] = get_block_length(s, &cur_index, &offset, &c_byte); -+ if (bh[0] == NULL) -+ goto read_failure; -+ b = 1; -+ -+ bytes = msblk->devblksize - offset; -+ compressed = SQUASHFS_COMPRESSED(c_byte); -+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); -+ -+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed -+ ? "" : "un", (unsigned int) c_byte); -+ -+ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) -+ goto block_release; -+ -+ for (; bytes < c_byte; b++) { -+ bh[b] = sb_getblk(s, ++cur_index); -+ if (bh[b] == NULL) -+ goto block_release; -+ bytes += msblk->devblksize; -+ } -+ ll_rw_block(READ, b - 1, bh + 1); -+ } -+ -+ if (compressed) { -+ int zlib_err = 0; -+ -+ /* -+ * uncompress block -+ */ -+ -+ mutex_lock(&msblk->read_data_mutex); -+ -+ msblk->stream.next_out = buffer; -+ msblk->stream.avail_out = srclength; -+ -+ for (bytes = 0; k < b; k++) { -+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); -+ -+ wait_on_buffer(bh[k]); -+ if (!buffer_uptodate(bh[k])) -+ goto release_mutex; -+ -+ msblk->stream.next_in = bh[k]->b_data + offset; -+ msblk->stream.avail_in = avail_bytes; -+ -+ if (k == 0) { -+ zlib_err = zlib_inflateInit(&msblk->stream); -+ if (zlib_err != Z_OK) { -+ ERROR("zlib_inflateInit returned unexpected result 0x%x," -+ " srclength %d\n", zlib_err, srclength); -+ goto release_mutex; -+ } -+ -+ if (avail_bytes == 0) { -+ offset = 0; -+ brelse(bh[k]); -+ continue; -+ } -+ } -+ -+ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); -+ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { -+ ERROR("zlib_inflate returned unexpected result 0x%x," -+ " srclength %d, avail_in %d, avail_out %d\n", zlib_err, -+ srclength, msblk->stream.avail_in, msblk->stream.avail_out); -+ goto release_mutex; -+ } -+ -+ bytes += avail_bytes; -+ offset = 0; -+ brelse(bh[k]); -+ } -+ -+ if (zlib_err != Z_STREAM_END) -+ goto release_mutex; -+ -+ zlib_err = zlib_inflateEnd(&msblk->stream); -+ if (zlib_err != Z_OK) { -+ ERROR("zlib_inflateEnd returned unexpected result 0x%x," -+ " srclength %d\n", zlib_err, srclength); -+ goto release_mutex; -+ } -+ bytes = msblk->stream.total_out; -+ mutex_unlock(&msblk->read_data_mutex); -+ } else { -+ int i; -+ -+ for(i = 0; i < b; i++) { -+ wait_on_buffer(bh[i]); -+ if (!buffer_uptodate(bh[i])) -+ goto block_release; -+ } -+ -+ for (bytes = 0; k < b; k++) { -+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); -+ -+ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes); -+ bytes += avail_bytes; -+ offset = 0; -+ brelse(bh[k]); -+ } -+ } -+ -+ if (next_index) -+ *next_index = index + c_byte + (length ? 0 : -+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2)); -+ -+ kfree(bh); -+ return bytes; -+ -+release_mutex: -+ mutex_unlock(&msblk->read_data_mutex); -+ -+block_release: -+ for (; k < b; k++) -+ brelse(bh[k]); -+ -+read_failure: -+ ERROR("sb_bread failed reading block 0x%x\n", cur_index); -+ kfree(bh); -+ return 0; -+} -+ -+ -+int squashfs_get_cached_block(struct super_block *s, void *buffer, -+ long long block, unsigned int offset, -+ int length, long long *next_block, -+ unsigned int *next_offset) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ int bytes, return_length = length; -+ struct squashfs_cache_entry *entry; -+ -+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset); -+ -+ while (1) { -+ entry = squashfs_cache_get(s, msblk->block_cache, block, 0); -+ bytes = entry->length - offset; -+ -+ if (entry->error || bytes < 1) { -+ return_length = 0; -+ goto finish; -+ } else if (bytes >= length) { -+ if (buffer) -+ memcpy(buffer, entry->data + offset, length); -+ if (entry->length - offset == length) { -+ *next_block = entry->next_index; -+ *next_offset = 0; -+ } else { -+ *next_block = block; -+ *next_offset = offset + length; -+ } -+ goto finish; -+ } else { -+ if (buffer) { -+ memcpy(buffer, entry->data + offset, bytes); -+ buffer = (char *) buffer + bytes; -+ } -+ block = entry->next_index; -+ squashfs_cache_put(msblk->block_cache, entry); -+ length -= bytes; -+ offset = 0; -+ } -+ } -+ -+finish: -+ squashfs_cache_put(msblk->block_cache, entry); -+ return return_length; -+} -diff -uNr a/fs/squashfs/cache.c b/fs/squashfs/cache.c ---- a/fs/squashfs/cache.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/cache.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,189 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * cache.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+struct squashfs_cache_entry *squashfs_cache_get(struct super_block *s, -+ struct squashfs_cache *cache, long long block, int length) -+{ -+ int i, n; -+ struct squashfs_cache_entry *entry; -+ -+ spin_lock(&cache->lock); -+ -+ while (1) { -+ for (i = 0; i < cache->entries && cache->entry[i].block != block; i++); -+ -+ if (i == cache->entries) { -+ if (cache->unused_blks == 0) { -+ cache->waiting ++; -+ spin_unlock(&cache->lock); -+ wait_event(cache->wait_queue, cache->unused_blks); -+ spin_lock(&cache->lock); -+ cache->waiting --; -+ continue; -+ } -+ -+ i = cache->next_blk; -+ for (n = 0; n < cache->entries; n++) { -+ if (cache->entry[i].locked == 0) -+ break; -+ i = (i + 1) % cache->entries; -+ } -+ -+ cache->next_blk = (i + 1) % cache->entries; -+ entry = &cache->entry[i]; -+ -+ cache->unused_blks --; -+ entry->block = block; -+ entry->locked = 1; -+ entry->pending = 1; -+ entry->waiting = 0; -+ entry->error = 0; -+ spin_unlock(&cache->lock); -+ -+ entry->length = squashfs_read_data(s, entry->data, -+ block, length, &entry->next_index, cache->block_size); -+ -+ spin_lock(&cache->lock); -+ -+ if (entry->length == 0) -+ entry->error = 1; -+ -+ entry->pending = 0; -+ spin_unlock(&cache->lock); -+ if (entry->waiting) -+ wake_up_all(&entry->wait_queue); -+ goto out; -+ } -+ -+ entry = &cache->entry[i]; -+ if (entry->locked == 0) -+ cache->unused_blks --; -+ entry->locked++; -+ -+ if (entry->pending) { -+ entry->waiting ++; -+ spin_unlock(&cache->lock); -+ wait_event(entry->wait_queue, !entry->pending); -+ goto out; -+ } -+ -+ spin_unlock(&cache->lock); -+ goto out; -+ } -+ -+out: -+ TRACE("Got %s %d, start block %lld, locked %d, error %d\n", i, -+ cache->name, entry->block, entry->locked, entry->error); -+ if (entry->error) -+ ERROR("Unable to read %s cache entry [%llx]\n", cache->name, block); -+ return entry; -+} -+ -+ -+void squashfs_cache_put(struct squashfs_cache *cache, -+ struct squashfs_cache_entry *entry) -+{ -+ spin_lock(&cache->lock); -+ entry->locked --; -+ if (entry->locked == 0) { -+ cache->unused_blks ++; -+ spin_unlock(&cache->lock); -+ if (cache->waiting) -+ wake_up(&cache->wait_queue); -+ } else -+ spin_unlock(&cache->lock); -+} -+ -+ -+void squashfs_cache_delete(struct squashfs_cache *cache) -+{ -+ int i; -+ -+ if (cache == NULL) -+ return; -+ -+ for (i = 0; i < cache->entries; i++) -+ if (cache->entry[i].data) { -+ if (cache->use_vmalloc) -+ vfree(cache->entry[i].data); -+ else -+ kfree(cache->entry[i].data); -+ } -+ -+ kfree(cache); -+} -+ -+ -+struct squashfs_cache *squashfs_cache_init(char *name, int entries, -+ int block_size, int use_vmalloc) -+{ -+ int i; -+ struct squashfs_cache *cache = kzalloc(sizeof(struct squashfs_cache) + -+ entries * sizeof(struct squashfs_cache_entry), GFP_KERNEL); -+ if (cache == NULL) { -+ ERROR("Failed to allocate %s cache\n", name); -+ goto failed; -+ } -+ -+ cache->next_blk = 0; -+ cache->unused_blks = entries; -+ cache->entries = entries; -+ cache->block_size = block_size; -+ cache->use_vmalloc = use_vmalloc; -+ cache->name = name; -+ cache->waiting = 0; -+ spin_lock_init(&cache->lock); -+ init_waitqueue_head(&cache->wait_queue); -+ -+ for (i = 0; i < entries; i++) { -+ init_waitqueue_head(&cache->entry[i].wait_queue); -+ cache->entry[i].block = SQUASHFS_INVALID_BLK; -+ cache->entry[i].data = use_vmalloc ? vmalloc(block_size) : -+ kmalloc(block_size, GFP_KERNEL); -+ if (cache->entry[i].data == NULL) { -+ ERROR("Failed to allocate %s cache entry\n", name); -+ goto cleanup; -+ } -+ } -+ -+ return cache; -+ -+cleanup: -+ squashfs_cache_delete(cache); -+failed: -+ return NULL; -+} -diff -uNr a/fs/squashfs/dir.c b/fs/squashfs/dir.c ---- a/fs/squashfs/dir.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/dir.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,216 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * dir.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.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 -+}; -+ -+static int get_dir_index_using_offset(struct super_block *s, -+ long long *next_block, unsigned int *next_offset, -+ long long index_start, unsigned int index_offset, int i_count, -+ long long f_pos) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ struct squashfs_dir_index index; -+ -+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", -+ i_count, (unsigned int) f_pos); -+ -+ f_pos -= 3; -+ if (f_pos == 0) -+ goto finish; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index sindex; -+ squashfs_get_cached_block(s, &sindex, index_start, index_offset, -+ sizeof(sindex), &index_start, &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); -+ } else -+ squashfs_get_cached_block(s, &index, index_start, index_offset, -+ sizeof(index), &index_start, &index_offset); -+ -+ if (index.index > f_pos) -+ break; -+ -+ squashfs_get_cached_block(s, NULL, index_start, index_offset, -+ index.size + 1, &index_start, &index_offset); -+ -+ length = index.index; -+ *next_block = index.start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ -+finish: -+ return length + 3; -+} -+ -+ -+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) -+{ -+ struct inode *i = file->f_dentry->d_inode; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; -+ struct squashfs_dir_header dirh; -+ struct squashfs_dir_entry *dire; -+ -+ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset); -+ -+ dire = kmalloc(sizeof(struct squashfs_dir_entry) + -+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL); -+ if (dire == NULL) { -+ ERROR("Failed to allocate squashfs_dir_entry\n"); -+ goto finish; -+ } -+ -+ while(file->f_pos < 3) { -+ char *name; -+ int size, i_ino; -+ -+ if(file->f_pos == 0) { -+ name = "."; -+ size = 1; -+ i_ino = i->i_ino; -+ } else { -+ name = ".."; -+ size = 2; -+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode; -+ } -+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n", -+ (unsigned int) dirent, name, size, (int) -+ file->f_pos, i_ino, squashfs_filetype_table[1]); -+ -+ if (filldir(dirent, name, size, file->f_pos, i_ino, -+ squashfs_filetype_table[1]) < 0) { -+ TRACE("Filldir returned less than 0\n"); -+ goto finish; -+ } -+ file->f_pos += size; -+ } -+ -+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, file->f_pos); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header sdirh; -+ -+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block, -+ next_offset, sizeof(sdirh), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block, -+ next_offset, sizeof(dirh), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry sdire; -+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block, -+ next_offset, sizeof(sdire), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block, -+ next_offset, sizeof(*dire), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block, -+ next_offset, dire->size + 1, &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (file->f_pos >= length) -+ continue; -+ -+ dire->name[dire->size + 1] = '\0'; -+ -+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n", -+ (unsigned int) dirent, dire->name, dire->size + 1, -+ (int) file->f_pos, dirh.start_block, dire->offset, -+ dirh.inode_number + dire->inode_number, -+ squashfs_filetype_table[dire->type]); -+ -+ if (filldir(dirent, dire->name, dire->size + 1, file->f_pos, -+ dirh.inode_number + dire->inode_number, -+ squashfs_filetype_table[dire->type]) < 0) { -+ TRACE("Filldir returned less than 0\n"); -+ goto finish; -+ } -+ file->f_pos = length; -+ } -+ } -+ -+finish: -+ kfree(dire); -+ return 0; -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ kfree(dire); -+ return 0; -+} -+ -+ -+const struct file_operations squashfs_dir_ops = { -+ .read = generic_read_dir, -+ .readdir = squashfs_readdir -+}; -diff -uNr a/fs/squashfs/export.c b/fs/squashfs/export.c ---- a/fs/squashfs/export.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/export.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,171 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * export.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)]; -+ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1); -+ squashfs_inode_t inode; -+ -+ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino); -+ -+ if (msblk->swap) { -+ squashfs_inode_t sinode; -+ -+ if (!squashfs_get_cached_block(s, &sinode, start, offset, -+ sizeof(sinode), &start, &offset)) -+ goto out; -+ SQUASHFS_SWAP_INODE_T((&inode), &sinode); -+ } else if (!squashfs_get_cached_block(s, &inode, start, offset, -+ sizeof(inode), &start, &offset)) -+ goto out; -+ -+ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode); -+ -+ return inode; -+ -+out: -+ return SQUASHFS_INVALID_BLK; -+} -+ -+ -+static struct dentry *squashfs_export_iget(struct super_block *s, -+ unsigned int inode_number) -+{ -+ squashfs_inode_t inode; -+ struct inode *i; -+ struct dentry *dentry; -+ -+ TRACE("Entered squashfs_export_iget\n"); -+ -+ inode = squashfs_inode_lookup(s, inode_number); -+ if(inode == SQUASHFS_INVALID_BLK) { -+ dentry = ERR_PTR(-ENOENT); -+ goto failure; -+ } -+ -+ i = squashfs_iget(s, inode, inode_number); -+ if(i == NULL) { -+ dentry = ERR_PTR(-EACCES); -+ goto failure; -+ } -+ -+ dentry = d_alloc_anon(i); -+ if (dentry == NULL) { -+ iput(i); -+ dentry = ERR_PTR(-ENOMEM); -+ } -+ -+failure: -+ return dentry; -+} -+ -+ -+static struct dentry *squashfs_fh_to_dentry(struct super_block *s, -+ 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(s, fid->i32.ino); -+} -+ -+ -+static struct dentry *squashfs_fh_to_parent(struct super_block *s, -+ 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(s, fid->i32.parent_ino); -+} -+ -+ -+static struct dentry *squashfs_get_parent(struct dentry *child) -+{ -+ struct inode *i = child->d_inode; -+ -+ TRACE("Entered squashfs_get_parent\n"); -+ -+ return squashfs_export_iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode); -+} -+ -+ -+int read_inode_lookup_table(struct super_block *s) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes); -+ -+ TRACE("In read_inode_lookup_table, length %d\n", length); -+ -+ /* Allocate inode lookup table */ -+ msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL); -+ if (msblk->inode_lookup_table == NULL) { -+ ERROR("Failed to allocate inode lookup table\n"); -+ return 0; -+ } -+ -+ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table, -+ sblk->lookup_table_start, length | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { -+ ERROR("unable to read inode lookup table\n"); -+ return 0; -+ } -+ -+ if (msblk->swap) { -+ int i; -+ long long block; -+ -+ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) { -+ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block), -+ &msblk->inode_lookup_table[i], 1); -+ msblk->inode_lookup_table[i] = block; -+ } -+ } -+ -+ return 1; -+} -+ -+ -+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 -uNr a/fs/squashfs/file.c b/fs/squashfs/file.c ---- a/fs/squashfs/file.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/file.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,430 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * file.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+ -+static struct meta_index *locate_meta_index(struct inode *inode, int index, int offset) -+{ -+ struct meta_index *meta = NULL; -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ int i; -+ -+ 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_NUMBER; i ++) { -+ if (msblk->meta_index[i].inode_number == inode->i_ino && -+ msblk->meta_index[i].offset >= offset && -+ msblk->meta_index[i].offset <= index && -+ msblk->meta_index[i].locked == 0) { -+ TRACE("locate_meta_index: entry %d, offset %d\n", i, -+ msblk->meta_index[i].offset); -+ meta = &msblk->meta_index[i]; -+ offset = meta->offset; -+ } -+ } -+ -+ if (meta) -+ meta->locked = 1; -+ -+not_allocated: -+ mutex_unlock(&msblk->meta_index_mutex); -+ -+ return meta; -+} -+ -+ -+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) { -+ msblk->meta_index = kmalloc(sizeof(struct meta_index) * -+ SQUASHFS_META_NUMBER, GFP_KERNEL); -+ if (msblk->meta_index == NULL) { -+ ERROR("Failed to allocate meta_index\n"); -+ goto failed; -+ } -+ for (i = 0; i < SQUASHFS_META_NUMBER; i++) { -+ msblk->meta_index[i].inode_number = 0; -+ msblk->meta_index[i].locked = 0; -+ } -+ msblk->next_meta_index = 0; -+ } -+ -+ for (i = SQUASHFS_META_NUMBER; i && -+ msblk->meta_index[msblk->next_meta_index].locked; i --) -+ msblk->next_meta_index = (msblk->next_meta_index + 1) % -+ SQUASHFS_META_NUMBER; -+ -+ 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_NUMBER; -+ -+ 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) -+{ -+ meta->locked = 0; -+ smp_mb(); -+} -+ -+ -+static int read_block_index(struct super_block *s, int blocks, char *block_list, -+ long long *start_block, int *offset) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ unsigned int *block_listp; -+ int block = 0; -+ -+ if (msblk->swap) { -+ char sblock_list[blocks << 2]; -+ -+ if (!squashfs_get_cached_block(s, sblock_list, *start_block, -+ *offset, blocks << 2, start_block, offset)) { -+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); -+ goto failure; -+ } -+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list), -+ ((unsigned int *)sblock_list), blocks); -+ } else { -+ if (!squashfs_get_cached_block(s, block_list, *start_block, -+ *offset, blocks << 2, start_block, offset)) { -+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); -+ goto failure; -+ } -+ } -+ -+ for (block_listp = (unsigned int *) block_list; blocks; -+ block_listp++, blocks --) -+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); -+ -+ return block; -+ -+failure: -+ return -1; -+} -+ -+ -+#define SIZE 256 -+ -+static inline int calculate_skip(int blocks) { -+ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES); -+ return skip >= 7 ? 7 : skip + 1; -+} -+ -+ -+static int get_meta_index(struct inode *inode, int index, -+ long long *index_block, int *index_offset, -+ long long *data_block, char *block_list) -+{ -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log); -+ int offset = 0; -+ struct meta_index *meta; -+ struct meta_entry *meta_entry; -+ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start; -+ int cur_offset = SQUASHFS_I(inode)->offset; -+ long long cur_data_block = SQUASHFS_I(inode)->start_block; -+ int i; -+ -+ index /= SQUASHFS_META_INDEXES * skip; -+ -+ while (offset < index) { -+ meta = locate_meta_index(inode, index, offset + 1); -+ -+ if (meta == NULL) { -+ meta = empty_meta_index(inode, offset + 1, skip); -+ if (meta == NULL) -+ goto all_done; -+ } else { -+ if(meta->entries == 0) -+ goto failed; -+ /* XXX */ -+ offset = index < meta->offset + meta->entries ? index : -+ meta->offset + meta->entries - 1; -+ /* XXX */ -+ meta_entry = &meta->meta_entry[offset - meta->offset]; -+ cur_index_block = meta_entry->index_block + sblk->inode_table_start; -+ 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); -+ } -+ -+ for (i = meta->offset + meta->entries; i <= index && -+ i < meta->offset + SQUASHFS_META_ENTRIES; i++) { -+ int blocks = skip * SQUASHFS_META_INDEXES; -+ -+ while (blocks) { -+ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : blocks; -+ int res = read_block_index(inode->i_sb, block, block_list, -+ &cur_index_block, &cur_offset); -+ -+ if (res == -1) -+ goto failed; -+ -+ cur_data_block += res; -+ blocks -= block; -+ } -+ -+ meta_entry = &meta->meta_entry[i - meta->offset]; -+ meta_entry->index_block = cur_index_block - sblk->inode_table_start; -+ 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; -+ -+ return offset * SQUASHFS_META_INDEXES * skip; -+ -+failed: -+ release_meta_index(inode, meta); -+ return -1; -+} -+ -+ -+long long read_blocklist(struct inode *inode, int index, -+ int readahead_blks, char *block_list, -+ unsigned short **block_p, unsigned int *bsize) -+{ -+ long long block_ptr; -+ int offset; -+ long long block; -+ int res = get_meta_index(inode, index, &block_ptr, &offset, &block, -+ block_list); -+ -+ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset" -+ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, block); -+ -+ if(res == -1) -+ goto failure; -+ -+ index -= res; -+ -+ while (index) { -+ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index; -+ int res = read_block_index(inode->i_sb, blocks, block_list, -+ &block_ptr, &offset); -+ if (res == -1) -+ goto failure; -+ block += res; -+ index -= blocks; -+ } -+ -+ if (read_block_index(inode->i_sb, 1, block_list, &block_ptr, &offset) == -1) -+ goto failure; -+ *bsize = *((unsigned int *) block_list); -+ -+ return block; -+ -+failure: -+ return 0; -+} -+ -+ -+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; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned char *block_list = NULL; -+ long long block; -+ unsigned int bsize, i; -+ int bytes; -+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT); -+ void *pageaddr; -+ struct squashfs_cache_entry *fragment = NULL; -+ char *data_ptr = msblk->read_page; -+ -+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1; -+ int start_index = page->index & ~mask; -+ int end_index = start_index | mask; -+ int file_end = i_size_read(inode) >> sblk->block_log; -+ int sparse = 0; -+ -+ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", -+ page->index, SQUASHFS_I(inode)->start_block); -+ -+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> -+ PAGE_CACHE_SHIFT)) -+ goto out; -+ -+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK -+ || index < file_end) { -+ block_list = kmalloc(SIZE, GFP_KERNEL); -+ if (block_list == NULL) { -+ ERROR("Failed to allocate block_list\n"); -+ goto error_out; -+ } -+ -+ block = (msblk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize); -+ if (block == 0) -+ goto error_out; -+ -+ if (bsize == 0) { /* hole */ -+ bytes = index == file_end ? -+ (i_size_read(inode) & (sblk->block_size - 1)) : sblk->block_size; -+ sparse = 1; -+ } else { -+ mutex_lock(&msblk->read_page_mutex); -+ -+ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, -+ bsize, NULL, sblk->block_size); -+ -+ if (bytes == 0) { -+ ERROR("Unable to read page, block %llx, size %x\n", block, bsize); -+ mutex_unlock(&msblk->read_page_mutex); -+ goto error_out; -+ } -+ } -+ } else { -+ fragment = get_cached_fragment(inode->i_sb, -+ SQUASHFS_I(inode)-> u.s1.fragment_start_block, -+ SQUASHFS_I(inode)->u.s1.fragment_size); -+ -+ if (fragment->error) { -+ ERROR("Unable to read page, block %llx, size %x\n", -+ SQUASHFS_I(inode)->u.s1.fragment_start_block, -+ (int) SQUASHFS_I(inode)->u.s1.fragment_size); -+ release_cached_fragment(msblk, fragment); -+ goto error_out; -+ } -+ bytes = i_size_read(inode) & (sblk->block_size - 1); -+ data_ptr = fragment->data + SQUASHFS_I(inode)->u.s1.fragment_offset; -+ } -+ -+ for (i = start_index; i <= end_index && bytes > 0; i++, -+ bytes -= PAGE_CACHE_SIZE, data_ptr += PAGE_CACHE_SIZE) { -+ struct page *push_page; -+ int avail = sparse ? 0 : min_t(unsigned 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, KM_USER0); -+ memcpy(pageaddr, data_ptr, avail); -+ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail); -+ kunmap_atomic(pageaddr, KM_USER0); -+ flush_dcache_page(push_page); -+ SetPageUptodate(push_page); -+skip_page: -+ unlock_page(push_page); -+ if(i != page->index) -+ page_cache_release(push_page); -+ } -+ -+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK -+ || index < file_end) { -+ if (!sparse) -+ mutex_unlock(&msblk->read_page_mutex); -+ kfree(block_list); -+ } else -+ release_cached_fragment(msblk, fragment); -+ -+ return 0; -+ -+error_out: -+ SetPageError(page); -+out: -+ pageaddr = kmap_atomic(page, KM_USER0); -+ memset(pageaddr, 0, PAGE_CACHE_SIZE); -+ kunmap_atomic(pageaddr, KM_USER0); -+ flush_dcache_page(page); -+ if (!PageError(page)) -+ SetPageUptodate(page); -+ unlock_page(page); -+ -+ kfree(block_list); -+ return 0; -+} -+ -+ -+const struct address_space_operations squashfs_aops = { -+ .readpage = squashfs_readpage -+}; -diff -uNr a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c ---- a/fs/squashfs/fragment.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/fragment.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,122 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * fragment.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+ -+int get_fragment_location(struct super_block *s, unsigned int fragment, -+ long long *fragment_start_block, -+ unsigned int *fragment_size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ long long start_block = -+ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; -+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); -+ struct squashfs_fragment_entry fragment_entry; -+ -+ if (msblk->swap) { -+ struct squashfs_fragment_entry sfragment_entry; -+ -+ if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset, -+ sizeof(sfragment_entry), &start_block, &offset)) -+ goto out; -+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); -+ } else -+ if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset, -+ sizeof(fragment_entry), &start_block, &offset)) -+ goto out; -+ -+ *fragment_start_block = fragment_entry.start_block; -+ *fragment_size = fragment_entry.size; -+ -+ return 1; -+ -+out: -+ return 0; -+} -+ -+ -+void release_cached_fragment(struct squashfs_sb_info *msblk, -+ struct squashfs_cache_entry *fragment) -+{ -+ squashfs_cache_put(msblk->fragment_cache, fragment); -+} -+ -+ -+struct squashfs_cache_entry *get_cached_fragment(struct super_block *s, -+ long long start_block, int length) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ -+ return squashfs_cache_get(s, msblk->fragment_cache, start_block, length); -+} -+ -+ -+int read_fragment_index_table(struct super_block *s) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments); -+ -+ if(length == 0) -+ return 1; -+ -+ /* Allocate fragment index table */ -+ msblk->fragment_index = kmalloc(length, GFP_KERNEL); -+ if (msblk->fragment_index == NULL) { -+ ERROR("Failed to allocate fragment index table\n"); -+ return 0; -+ } -+ -+ if (!squashfs_read_data(s, (char *) msblk->fragment_index, -+ sblk->fragment_table_start, length | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { -+ ERROR("unable to read fragment index table\n"); -+ return 0; -+ } -+ -+ if (msblk->swap) { -+ int i; -+ long long fragment; -+ -+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) { -+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), -+ &msblk->fragment_index[i], 1); -+ msblk->fragment_index[i] = fragment; -+ } -+ } -+ -+ return 1; -+} -diff -uNr a/fs/squashfs/id.c b/fs/squashfs/id.c ---- a/fs/squashfs/id.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/id.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,97 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * id.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+ -+int get_id(struct super_block *s, unsigned int index, unsigned int *id) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ long long start_block = msblk->id_table[SQUASHFS_ID_BLOCK(index)]; -+ int offset = SQUASHFS_ID_BLOCK_OFFSET(index); -+ -+ if (msblk->swap) { -+ unsigned int sid; -+ -+ if (!squashfs_get_cached_block(s, &sid, start_block, offset, -+ sizeof(unsigned int), &start_block, &offset)) -+ goto out; -+ SQUASHFS_SWAP_INTS((&sid), id, 1); -+ } else -+ if (!squashfs_get_cached_block(s, id, start_block, offset, -+ sizeof(unsigned int), &start_block, &offset)) -+ goto out; -+ -+ return 1; -+ -+out: -+ return 0; -+} -+ -+ -+int read_id_index_table(struct super_block *s) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned int length = SQUASHFS_ID_BLOCK_BYTES(sblk->no_ids); -+ -+ TRACE("In read_id_index_table, length %d\n", length); -+ -+ /* Allocate id index table */ -+ msblk->id_table = kmalloc(length, GFP_KERNEL); -+ if (msblk->id_table == NULL) { -+ ERROR("Failed to allocate id index table\n"); -+ return 0; -+ } -+ -+ if (!squashfs_read_data(s, (char *) msblk->id_table, -+ sblk->id_table_start, length | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { -+ ERROR("unable to read id index table\n"); -+ return 0; -+ } -+ -+ if (msblk->swap) { -+ int i; -+ long long block; -+ -+ for (i = 0; i < SQUASHFS_ID_BLOCKS(sblk->no_ids); i++) { -+ SQUASHFS_SWAP_ID_BLOCKS((&block), &msblk->id_table[i], 1); -+ msblk->id_table[i] = block; -+ } -+ } -+ -+ return 1; -+} -diff -uNr a/fs/squashfs/inode.c b/fs/squashfs/inode.c ---- a/fs/squashfs/inode.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/inode.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,340 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * inode.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+ -+static int squashfs_new_inode(struct super_block *s, struct inode *i, -+ struct squashfs_base_inode_header *inodeb) -+{ -+ if(get_id(s, inodeb->uid, &i->i_uid) == 0) -+ goto out; -+ if(get_id(s, inodeb->guid, &i->i_gid) == 0) -+ goto out; -+ -+ i->i_ino = inodeb->inode_number; -+ i->i_mtime.tv_sec = inodeb->mtime; -+ i->i_atime.tv_sec = inodeb->mtime; -+ i->i_ctime.tv_sec = inodeb->mtime; -+ i->i_mode = inodeb->mode; -+ i->i_size = 0; -+ -+ return 1; -+ -+out: -+ return 0; -+} -+ -+ -+struct inode *squashfs_iget(struct super_block *s, -+ squashfs_inode_t inode, unsigned int inode_number) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct inode *i = iget_locked(s, inode_number); -+ -+ TRACE("Entered squashfs_iget\n"); -+ -+ if(i && (i->i_state & I_NEW)) { -+ (msblk->read_inode)(i, inode); -+ unlock_new_inode(i); -+ } -+ -+ return i; -+} -+ -+ -+int squashfs_read_inode(struct inode *i, squashfs_inode_t inode) -+{ -+ struct super_block *s = i->i_sb; -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start; -+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); -+ long long next_block; -+ unsigned int next_offset; -+ union squashfs_inode_header id, sid; -+ struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base; -+ -+ TRACE("Entered squashfs_read_inode\n"); -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodeb, block, offset, -+ sizeof(*sinodeb), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, sizeof(*sinodeb)); -+ } else -+ if (!squashfs_get_cached_block(s, inodeb, block, offset, -+ sizeof(*inodeb), &next_block, &next_offset)) -+ goto failed_read; -+ -+ if(squashfs_new_inode(s, i, inodeb) == 0) -+ goto failed_read; -+ -+ switch(inodeb->inode_type) { -+ case SQUASHFS_FILE_TYPE: { -+ unsigned int frag_size; -+ long long frag_blk; -+ struct squashfs_reg_inode_header *inodep = &id.reg; -+ struct squashfs_reg_inode_header *sinodep = &sid.reg; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ frag_blk = SQUASHFS_INVALID_BLK; -+ -+ if (inodep->fragment != SQUASHFS_INVALID_FRAG) -+ if(!get_fragment_location(s, inodep->fragment, &frag_blk, -+ &frag_size)) -+ goto failed_read; -+ -+ i->i_nlink = 1; -+ i->i_size = inodep->file_size; -+ i->i_fop = &generic_ro_fops; -+ i->i_mode |= S_IFREG; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; -+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; -+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->u.s1.block_list_start = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ i->i_data.a_ops = &squashfs_aops; -+ -+ TRACE("File inode %x:%x, start_block %llx, " -+ "block_list_start %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, next_block, -+ next_offset); -+ break; -+ } -+ case SQUASHFS_LREG_TYPE: { -+ unsigned int frag_size; -+ long long frag_blk; -+ struct squashfs_lreg_inode_header *inodep = &id.lreg; -+ struct squashfs_lreg_inode_header *sinodep = &sid.lreg; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ frag_blk = SQUASHFS_INVALID_BLK; -+ -+ if (inodep->fragment != SQUASHFS_INVALID_FRAG) -+ if (!get_fragment_location(s, inodep->fragment, &frag_blk, -+ &frag_size)) -+ goto failed_read; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->file_size; -+ i->i_fop = &generic_ro_fops; -+ i->i_mode |= S_IFREG; -+ i->i_blocks = ((inodep->file_size - inodep->sparse - 1) >> 9) + 1; -+ -+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; -+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; -+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->u.s1.block_list_start = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ i->i_data.a_ops = &squashfs_aops; -+ -+ TRACE("File inode %x:%x, start_block %llx, " -+ "block_list_start %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, next_block, -+ next_offset); -+ break; -+ } -+ case SQUASHFS_DIR_TYPE: { -+ struct squashfs_dir_inode_header *inodep = &id.dir; -+ struct squashfs_dir_inode_header *sinodep = &sid.dir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops; -+ i->i_fop = &squashfs_dir_ops; -+ i->i_mode |= S_IFDIR; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = 0; -+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; -+ -+ TRACE("Directory inode %x:%x, start_block %x, offset " -+ "%x\n", SQUASHFS_INODE_BLK(inode), -+ offset, inodep->start_block, -+ inodep->offset); -+ break; -+ } -+ case SQUASHFS_LDIR_TYPE: { -+ struct squashfs_ldir_inode_header *inodep = &id.ldir; -+ struct squashfs_ldir_inode_header *sinodep = &sid.ldir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops; -+ i->i_fop = &squashfs_dir_ops; -+ i->i_mode |= S_IFDIR; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; -+ SQUASHFS_I(i)->u.s2.directory_index_offset = next_offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = inodep->i_count; -+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; -+ -+ TRACE("Long directory inode %x:%x, start_block %x, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, inodep->offset); -+ break; -+ } -+ case SQUASHFS_SYMLINK_TYPE: { -+ struct squashfs_symlink_inode_header *inodep = &id.symlink; -+ struct squashfs_symlink_inode_header *sinodep = &sid.symlink; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->symlink_size; -+ i->i_op = &page_symlink_inode_operations; -+ i->i_data.a_ops = &squashfs_symlink_aops; -+ i->i_mode |= S_IFLNK; -+ SQUASHFS_I(i)->start_block = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ -+ TRACE("Symbolic link inode %x:%x, start_block %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_BLKDEV_TYPE: -+ case SQUASHFS_CHRDEV_TYPE: { -+ struct squashfs_dev_inode_header *inodep = &id.dev; -+ struct squashfs_dev_inode_header *sinodep = &sid.dev; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ? -+ S_IFCHR : S_IFBLK; -+ init_special_inode(i, i->i_mode, old_decode_dev(inodep->rdev)); -+ -+ TRACE("Device inode %x:%x, rdev %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, inodep->rdev); -+ break; -+ } -+ case SQUASHFS_FIFO_TYPE: -+ case SQUASHFS_SOCKET_TYPE: { -+ struct squashfs_ipc_inode_header *inodep = &id.ipc; -+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, sinodep, block, offset, -+ sizeof(*sinodep), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, inodep, block, offset, -+ sizeof(*inodep), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) -+ ? S_IFIFO : S_IFSOCK; -+ init_special_inode(i, i->i_mode, 0); -+ break; -+ } -+ default: -+ ERROR("Unknown inode type %d in squashfs_iget!\n", -+ inodeb->inode_type); -+ goto failed_read1; -+ } -+ -+ return 1; -+ -+failed_read: -+ ERROR("Unable to read inode [%llx:%x]\n", block, offset); -+ -+failed_read1: -+ make_bad_inode(i); -+ return 0; -+} -diff -uNr a/fs/squashfs/Makefile b/fs/squashfs/Makefile ---- a/fs/squashfs/Makefile 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/Makefile 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,8 @@ -+# -+# 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 -+#squashfs-y += squashfs2_0.o -diff -uNr a/fs/squashfs/namei.c b/fs/squashfs/namei.c ---- a/fs/squashfs/namei.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/namei.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,200 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * namei.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+ -+static int get_dir_index_using_name(struct super_block *s, -+ long long *next_block, unsigned int *next_offset, -+ long long index_start, unsigned int index_offset, int i_count, -+ const char *name, int size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ struct squashfs_dir_index *index; -+ char *str; -+ -+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); -+ -+ str = kmalloc(sizeof(struct squashfs_dir_index) + -+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL); -+ if (str == NULL) { -+ ERROR("Failed to allocate squashfs_dir_index\n"); -+ goto failure; -+ } -+ -+ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1); -+ strncpy(str, name, size); -+ str[size] = '\0'; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index sindex; -+ squashfs_get_cached_block(s, &sindex, index_start, index_offset, -+ sizeof(sindex), &index_start, &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex); -+ } else -+ squashfs_get_cached_block(s, index, index_start, index_offset, -+ sizeof(struct squashfs_dir_index), &index_start, &index_offset); -+ -+ squashfs_get_cached_block(s, index->name, index_start, index_offset, -+ index->size + 1, &index_start, &index_offset); -+ -+ index->name[index->size + 1] = '\0'; -+ -+ if (strcmp(index->name, str) > 0) -+ break; -+ -+ length = index->index; -+ *next_block = index->start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ kfree(str); -+ -+failure: -+ return length + 3; -+} -+ -+ -+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ const unsigned char *name = dentry->d_name.name; -+ int len = dentry->d_name.len; -+ struct inode *inode = NULL; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; -+ struct squashfs_dir_header dirh; -+ struct squashfs_dir_entry *dire; -+ -+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); -+ -+ dire = kmalloc(sizeof(struct squashfs_dir_entry) + -+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL); -+ if (dire == NULL) { -+ ERROR("Failed to allocate squashfs_dir_entry\n"); -+ goto exit_lookup; -+ } -+ -+ if (len > SQUASHFS_NAME_LEN) -+ goto exit_lookup; -+ -+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, name, len); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header sdirh; -+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block, -+ next_offset, sizeof(sdirh), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block, -+ next_offset, sizeof(dirh), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry sdire; -+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block, -+ next_offset, sizeof(sdire), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block, -+ next_offset, sizeof(*dire), &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block, -+ next_offset, dire->size + 1, &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (name[0] < dire->name[0]) -+ goto exit_lookup; -+ -+ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) { -+ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, -+ dire->offset); -+ -+ TRACE("calling squashfs_iget for directory entry %s, inode" -+ " %x:%x, %d\n", name, dirh.start_block, dire->offset, -+ dirh.inode_number + dire->inode_number); -+ -+ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number); -+ -+ goto exit_lookup; -+ } -+ } -+ } -+ -+exit_lookup: -+ kfree(dire); -+ if (inode) -+ return d_splice_alias(inode, dentry); -+ d_add(dentry, inode); -+ return ERR_PTR(0); -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ goto exit_lookup; -+} -+ -+ -+const struct inode_operations squashfs_dir_inode_ops = { -+ .lookup = squashfs_lookup -+}; -diff -uNr a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c ---- a/fs/squashfs/squashfs2_0.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/squashfs2_0.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,740 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs2_0.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+ -+#include "squashfs.h" -+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir); -+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *, -+ struct nameidata *); -+ -+static struct file_operations squashfs_dir_ops_2 = { -+ .read = generic_read_dir, -+ .readdir = squashfs_readdir_2 -+}; -+ -+static struct inode_operations squashfs_dir_inode_ops_2 = { -+ .lookup = squashfs_lookup_2 -+}; -+ -+static unsigned char squashfs_filetype_table[] = { -+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK -+}; -+ -+static int read_fragment_index_table_2(struct super_block *s) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2 -+ (sblk->fragments), GFP_KERNEL))) { -+ ERROR("Failed to allocate uid/gid table\n"); -+ return 0; -+ } -+ -+ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && -+ !squashfs_read_data(s, (char *) -+ msblk->fragment_index_2, -+ sblk->fragment_table_start, -+ SQUASHFS_FRAGMENT_INDEX_BYTES_2 -+ (sblk->fragments) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { -+ ERROR("unable to read fragment index table\n"); -+ return 0; -+ } -+ -+ if (msblk->swap) { -+ int i; -+ unsigned int fragment; -+ -+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments); -+ i++) { -+ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment), -+ &msblk->fragment_index_2[i], 1); -+ msblk->fragment_index_2[i] = fragment; -+ } -+ } -+ -+ return 1; -+} -+ -+ -+static int get_fragment_location_2(struct super_block *s, unsigned int fragment, -+ long long *fragment_start_block, -+ unsigned int *fragment_size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ long long start_block = -+ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)]; -+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment); -+ struct squashfs_fragment_entry_2 fragment_entry; -+ -+ if (msblk->swap) { -+ struct squashfs_fragment_entry_2 sfragment_entry; -+ -+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, -+ start_block, offset, -+ sizeof(sfragment_entry), &start_block, -+ &offset)) -+ goto out; -+ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, -+ start_block, offset, -+ sizeof(fragment_entry), &start_block, -+ &offset)) -+ goto out; -+ -+ *fragment_start_block = fragment_entry.start_block; -+ *fragment_size = fragment_entry.size; -+ -+ return 1; -+ -+out: -+ return 0; -+} -+ -+ -+static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, -+ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) -+{ -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ i->i_ino = ino; -+ i->i_mtime.tv_sec = sblk->mkfs_time; -+ i->i_atime.tv_sec = sblk->mkfs_time; -+ i->i_ctime.tv_sec = sblk->mkfs_time; -+ i->i_uid = msblk->uid[inodeb->uid]; -+ i->i_mode = inodeb->mode; -+ i->i_nlink = 1; -+ i->i_size = 0; -+ if (inodeb->guid == SQUASHFS_GUIDS) -+ i->i_gid = i->i_uid; -+ else -+ i->i_gid = msblk->guid[inodeb->guid]; -+} -+ -+ -+static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode) -+{ -+ struct super_block *s = i->i_sb; -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned int block = SQUASHFS_INODE_BLK(inode) + -+ sblk->inode_table_start; -+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); -+ unsigned int ino = SQUASHFS_MK_VFS_INODE(block - -+ sblk->inode_table_start, offset); -+ long long next_block; -+ unsigned int next_offset; -+ union squashfs_inode_header_2 id, sid; -+ struct squashfs_base_inode_header_2 *inodeb = &id.base, -+ *sinodeb = &sid.base; -+ -+ TRACE("Entered squashfs_read_inode_2\n"); -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, -+ offset, sizeof(*sinodeb), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb, -+ sizeof(*sinodeb)); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) inodeb, block, -+ offset, sizeof(*inodeb), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ squashfs_new_inode(msblk, i, inodeb, ino); -+ -+ switch(inodeb->inode_type) { -+ case SQUASHFS_FILE_TYPE: { -+ struct squashfs_reg_inode_header_2 *inodep = &id.reg; -+ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg; -+ long long frag_blk; -+ unsigned int frag_size = 0; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ frag_blk = SQUASHFS_INVALID_BLK; -+ if (inodep->fragment != SQUASHFS_INVALID_FRAG && -+ !get_fragment_location_2(s, -+ inodep->fragment, &frag_blk, &frag_size)) -+ goto failed_read; -+ -+ i->i_size = inodep->file_size; -+ i->i_fop = &generic_ro_fops; -+ i->i_mode |= S_IFREG; -+ i->i_mtime.tv_sec = inodep->mtime; -+ i->i_atime.tv_sec = inodep->mtime; -+ i->i_ctime.tv_sec = inodep->mtime; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; -+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; -+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->u.s1.block_list_start = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ i->i_data.a_ops = &squashfs_aops; -+ -+ TRACE("File inode %x:%x, start_block %x, " -+ "block_list_start %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, next_block, -+ next_offset); -+ break; -+ } -+ case SQUASHFS_DIR_TYPE: { -+ struct squashfs_dir_inode_header_2 *inodep = &id.dir; -+ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops_2; -+ i->i_fop = &squashfs_dir_ops_2; -+ i->i_mode |= S_IFDIR; -+ i->i_mtime.tv_sec = inodep->mtime; -+ i->i_atime.tv_sec = inodep->mtime; -+ i->i_ctime.tv_sec = inodep->mtime; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = 0; -+ SQUASHFS_I(i)->u.s2.parent_inode = 0; -+ -+ TRACE("Directory inode %x:%x, start_block %x, offset " -+ "%x\n", SQUASHFS_INODE_BLK(inode), -+ offset, inodep->start_block, -+ inodep->offset); -+ break; -+ } -+ case SQUASHFS_LDIR_TYPE: { -+ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir; -+ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep, -+ sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops_2; -+ i->i_fop = &squashfs_dir_ops_2; -+ i->i_mode |= S_IFDIR; -+ i->i_mtime.tv_sec = inodep->mtime; -+ i->i_atime.tv_sec = inodep->mtime; -+ i->i_ctime.tv_sec = inodep->mtime; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; -+ SQUASHFS_I(i)->u.s2.directory_index_offset = -+ next_offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = -+ inodep->i_count; -+ SQUASHFS_I(i)->u.s2.parent_inode = 0; -+ -+ TRACE("Long directory inode %x:%x, start_block %x, " -+ "offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, inodep->offset); -+ break; -+ } -+ case SQUASHFS_SYMLINK_TYPE: { -+ struct squashfs_symlink_inode_header_2 *inodep = -+ &id.symlink; -+ struct squashfs_symlink_inode_header_2 *sinodep = -+ &sid.symlink; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep, -+ sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep->symlink_size; -+ i->i_op = &page_symlink_inode_operations; -+ i->i_data.a_ops = &squashfs_symlink_aops; -+ i->i_mode |= S_IFLNK; -+ SQUASHFS_I(i)->start_block = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ -+ TRACE("Symbolic link inode %x:%x, start_block %llx, " -+ "offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_BLKDEV_TYPE: -+ case SQUASHFS_CHRDEV_TYPE: { -+ struct squashfs_dev_inode_header_2 *inodep = &id.dev; -+ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ i->i_mode |= (inodeb->inode_type == -+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : -+ S_IFBLK; -+ init_special_inode(i, i->i_mode, -+ old_decode_dev(inodep->rdev)); -+ -+ TRACE("Device inode %x:%x, rdev %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->rdev); -+ break; -+ } -+ case SQUASHFS_FIFO_TYPE: -+ case SQUASHFS_SOCKET_TYPE: { -+ -+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) -+ ? S_IFIFO : S_IFSOCK; -+ init_special_inode(i, i->i_mode, 0); -+ break; -+ } -+ default: -+ ERROR("Unknown inode type %d in squashfs_iget!\n", -+ inodeb->inode_type); -+ goto failed_read1; -+ } -+ -+ return 1; -+ -+failed_read: -+ ERROR("Unable to read inode [%x:%x]\n", block, offset); -+ -+failed_read1: -+ return 0; -+} -+ -+ -+static int get_dir_index_using_offset(struct super_block *s, long long -+ *next_block, unsigned int *next_offset, -+ long long index_start, -+ unsigned int index_offset, int i_count, -+ long long f_pos) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ struct squashfs_dir_index_2 index; -+ -+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", -+ i_count, (unsigned int) f_pos); -+ -+ if (f_pos == 0) -+ goto finish; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index_2 sindex; -+ squashfs_get_cached_block(s, (char *) &sindex, -+ index_start, index_offset, -+ sizeof(sindex), &index_start, -+ &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex); -+ } else -+ squashfs_get_cached_block(s, (char *) &index, -+ index_start, index_offset, -+ sizeof(index), &index_start, -+ &index_offset); -+ -+ if (index.index > f_pos) -+ break; -+ -+ squashfs_get_cached_block(s, NULL, index_start, index_offset, -+ index.size + 1, &index_start, -+ &index_offset); -+ -+ length = index.index; -+ *next_block = index.start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ -+finish: -+ return length; -+} -+ -+ -+static int get_dir_index_using_name(struct super_block *s, long long -+ *next_block, unsigned int *next_offset, -+ long long index_start, -+ unsigned int index_offset, int i_count, -+ const char *name, int size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ struct squashfs_dir_index_2 *index; -+ char *str; -+ -+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); -+ -+ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + -+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { -+ ERROR("Failed to allocate squashfs_dir_index\n"); -+ goto failure; -+ } -+ -+ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1); -+ strncpy(str, name, size); -+ str[size] = '\0'; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index_2 sindex; -+ squashfs_get_cached_block(s, (char *) &sindex, -+ index_start, index_offset, -+ sizeof(sindex), &index_start, -+ &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex); -+ } else -+ squashfs_get_cached_block(s, (char *) index, -+ index_start, index_offset, -+ sizeof(struct squashfs_dir_index_2), -+ &index_start, &index_offset); -+ -+ squashfs_get_cached_block(s, index->name, index_start, -+ index_offset, index->size + 1, -+ &index_start, &index_offset); -+ -+ index->name[index->size + 1] = '\0'; -+ -+ if (strcmp(index->name, str) > 0) -+ break; -+ -+ length = index->index; -+ *next_block = index->start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ kfree(str); -+failure: -+ return length; -+} -+ -+ -+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir) -+{ -+ struct inode *i = file->f_dentry->d_inode; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, -+ dir_count; -+ struct squashfs_dir_header_2 dirh; -+ struct squashfs_dir_entry_2 *dire; -+ -+ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); -+ -+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + -+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { -+ ERROR("Failed to allocate squashfs_dir_entry\n"); -+ goto finish; -+ } -+ -+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, -+ file->f_pos); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header_2 sdirh; -+ -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, -+ next_block, next_offset, sizeof(sdirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, -+ next_block, next_offset, sizeof(dirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry_2 sdire; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ &sdire, next_block, next_offset, -+ sizeof(sdire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ dire, next_block, next_offset, -+ sizeof(*dire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, -+ dire->size + 1, &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (file->f_pos >= length) -+ continue; -+ -+ dire->name[dire->size + 1] = '\0'; -+ -+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", -+ (unsigned int) dirent, dire->name, -+ dire->size + 1, (int) file->f_pos, -+ dirh.start_block, dire->offset, -+ squashfs_filetype_table[dire->type]); -+ -+ if (filldir(dirent, dire->name, dire->size + 1, -+ file->f_pos, SQUASHFS_MK_VFS_INODE( -+ dirh.start_block, dire->offset), -+ squashfs_filetype_table[dire->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", next_block, -+ next_offset); -+ kfree(dire); -+ return 0; -+} -+ -+ -+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ const unsigned char *name = dentry->d_name.name; -+ int len = dentry->d_name.len; -+ struct inode *inode = NULL; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, -+ dir_count; -+ struct squashfs_dir_header_2 dirh; -+ struct squashfs_dir_entry_2 *dire; -+ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; -+ -+ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset); -+ -+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + -+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { -+ ERROR("Failed to allocate squashfs_dir_entry\n"); -+ goto exit_loop; -+ } -+ -+ if (len > SQUASHFS_NAME_LEN) -+ goto exit_loop; -+ -+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, name, -+ len); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header_2 sdirh; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, -+ next_block, next_offset, sizeof(sdirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, -+ next_block, next_offset, sizeof(dirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry_2 sdire; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ &sdire, next_block,next_offset, -+ sizeof(sdire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ dire, next_block,next_offset, -+ sizeof(*dire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, dire->size + 1, -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (sorted && name[0] < dire->name[0]) -+ goto exit_loop; -+ -+ if ((len == dire->size + 1) && !strncmp(name, -+ dire->name, len)) { -+ squashfs_inode_t ino = -+ SQUASHFS_MKINODE(dirh.start_block, -+ dire->offset); -+ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block, -+ dire->offset); -+ -+ TRACE("calling squashfs_iget for directory " -+ "entry %s, inode %x:%x, %lld\n", name, -+ dirh.start_block, dire->offset, ino); -+ -+ inode = squashfs_iget(i->i_sb, ino, inode_number); -+ -+ goto exit_loop; -+ } -+ } -+ } -+ -+exit_loop: -+ kfree(dire); -+ d_add(dentry, inode); -+ return ERR_PTR(0); -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ goto exit_loop; -+} -+ -+ -+int squashfs_2_0_supported(struct squashfs_sb_info *msblk) -+{ -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ msblk->read_inode = squashfs_read_inode_2; -+ msblk->read_fragment_index_table = read_fragment_index_table_2; -+ -+ sblk->bytes_used = sblk->bytes_used_2; -+ sblk->uid_start = sblk->uid_start_2; -+ sblk->guid_start = sblk->guid_start_2; -+ sblk->inode_table_start = sblk->inode_table_start_2; -+ sblk->directory_table_start = sblk->directory_table_start_2; -+ sblk->fragment_table_start = sblk->fragment_table_start_2; -+ -+ return 1; -+} -diff -uNr a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h ---- a/fs/squashfs/squashfs.h 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/squashfs.h 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,122 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs.h -+ */ -+ -+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+#endif -+ -+#ifdef SQUASHFS_TRACE -+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) -+#else -+#define TRACE(s, args...) {} -+#endif -+ -+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) -+ -+#define SERROR(s, args...) do { \ -+ if (!silent) \ -+ printk(KERN_ERR "SQUASHFS error: "s, ## args);\ -+ } while(0) -+ -+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) -+ -+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode) -+{ -+ return list_entry(inode, struct squashfs_inode_info, vfs_inode); -+} -+ -+/* block.c */ -+extern unsigned int squashfs_read_data(struct super_block *, char *, -+ long long, unsigned int, long long *, int); -+extern int squashfs_get_cached_block(struct super_block *, void *, -+ long long, unsigned int, int, long long *, unsigned int *); -+ -+/* cache.c */ -+extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *, -+ struct squashfs_cache *, long long, int); -+extern void squashfs_cache_put(struct squashfs_cache *, -+ struct squashfs_cache_entry *); -+extern void squashfs_cache_delete(struct squashfs_cache *); -+extern struct squashfs_cache *squashfs_cache_init(char *, int, int, int); -+ -+/* export.c */ -+extern int read_inode_lookup_table(struct super_block *); -+ -+/* file.c */ -+extern long long read_blocklist(struct inode *, int, int, char *, -+ unsigned short **, unsigned int *); -+ -+/* fragment.c */ -+extern int get_fragment_location(struct super_block *, unsigned int, -+ long long *, unsigned int *); -+extern void release_cached_fragment(struct squashfs_sb_info *, -+ struct squashfs_cache_entry *); -+extern struct squashfs_cache_entry *get_cached_fragment(struct super_block *, -+ long long, int); -+extern int read_fragment_index_table(struct super_block *); -+ -+/* id.c */ -+extern int get_id(struct super_block *, unsigned int, unsigned int *); -+extern int read_id_index_table(struct super_block *); -+ -+/* inode.c */ -+extern struct inode *squashfs_iget(struct super_block *, squashfs_inode_t, -+ unsigned int); -+extern int squashfs_read_inode(struct inode *, squashfs_inode_t); -+ -+/* -+ * Inodes and files 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; -+ -+/* namei.c */ -+extern const struct inode_operations squashfs_dir_inode_ops; -+ -+/* symlink.c */ -+extern const struct address_space_operations squashfs_symlink_aops; -+ -+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk); -+#else -+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk) -+{ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk); -+#else -+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk) -+{ -+ return 0; -+} -+#endif -diff -uNr a/fs/squashfs/super.c b/fs/squashfs/super.c ---- a/fs/squashfs/super.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/super.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,381 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * super.c -+ */ -+ -+#include <linux/squashfs_fs.h> -+#include <linux/module.h> -+#include <linux/zlib.h> -+#include <linux/fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+#include <linux/buffer_head.h> -+#include <linux/vfs.h> -+#include <linux/vmalloc.h> -+#include <linux/spinlock.h> -+#include <linux/smp_lock.h> -+#include <linux/exportfs.h> -+ -+#include "squashfs.h" -+ -+static struct file_system_type squashfs_fs_type; -+static struct super_operations squashfs_super_ops; -+ -+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent) -+{ -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ msblk->read_inode = squashfs_read_inode; -+ msblk->read_blocklist = read_blocklist; -+ msblk->read_fragment_index_table = read_fragment_index_table; -+ -+ if (sblk->s_major == 1) { -+ if (!squashfs_1_0_supported(msblk)) { -+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems " -+ "are unsupported\n"); -+ SERROR("Please recompile with Squashfs 1.0 support enabled\n"); -+ return 0; -+ } -+ } else if (sblk->s_major == 2) { -+ if (!squashfs_2_0_supported(msblk)) { -+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems " -+ "are unsupported\n"); -+ SERROR("Please recompile with Squashfs 2.0 support enabled\n"); -+ return 0; -+ } -+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor > -+ SQUASHFS_MINOR) { -+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d " -+ "filesystem\n", sblk->s_major, sblk->s_minor); -+ SERROR("Please update your kernel\n"); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+ -+static int squashfs_fill_super(struct super_block *s, void *data, int silent) -+{ -+ struct squashfs_sb_info *msblk; -+ struct squashfs_super_block *sblk; -+ char b[BDEVNAME_SIZE]; -+ struct inode *root; -+ -+ TRACE("Entered squashfs_fill_superblock\n"); -+ -+ s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL); -+ if (s->s_fs_info == NULL) { -+ ERROR("Failed to allocate superblock\n"); -+ goto failure; -+ } -+ msblk = s->s_fs_info; -+ -+ msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()); -+ if (msblk->stream.workspace == NULL) { -+ ERROR("Failed to allocate zlib workspace\n"); -+ goto failure; -+ } -+ sblk = &msblk->sblk; -+ -+ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); -+ msblk->devblksize_log2 = ffz(~msblk->devblksize); -+ -+ mutex_init(&msblk->read_data_mutex); -+ mutex_init(&msblk->read_page_mutex); -+ mutex_init(&msblk->meta_index_mutex); -+ -+ /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not -+ * beyond filesystem end. As we're using squashfs_read_data to read sblk here, -+ * first set sblk->bytes_used to a useful value */ -+ sblk->bytes_used = sizeof(struct squashfs_super_block); -+ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, -+ sizeof(struct squashfs_super_block) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) { -+ SERROR("unable to read superblock\n"); -+ goto failed_mount; -+ } -+ -+ /* Check it is a SQUASHFS superblock */ -+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { -+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { -+ struct squashfs_super_block ssblk; -+ -+ WARNING("Mounting a different endian SQUASHFS filesystem on %s\n", -+ bdevname(s->s_bdev, b)); -+ -+ //SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); -+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); -+ msblk->swap = 1; -+ } else { -+ SERROR("Can't find a SQUASHFS superblock on %s\n", -+ bdevname(s->s_bdev, b)); -+ goto failed_mount; -+ } -+ } -+ -+ /* Check the MAJOR & MINOR versions */ -+ if(!supported_squashfs_filesystem(msblk, silent)) -+ goto failed_mount; -+ -+ /* Check the filesystem does not extend beyond the end of the -+ block device */ -+ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) -+ goto failed_mount; -+ -+ /* Check the root inode for sanity */ -+ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) -+ goto failed_mount; -+ -+ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); -+ TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sblk->flags) -+ ? "un" : ""); -+ TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sblk->flags) -+ ? "un" : ""); -+ TRACE("Check data is %spresent in the filesystem\n", -+ SQUASHFS_CHECK_DATA(sblk->flags) ? "" : "not "); -+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used); -+ TRACE("Block size %d\n", sblk->block_size); -+ TRACE("Number of inodes %d\n", sblk->inodes); -+ if (sblk->s_major > 1) -+ TRACE("Number of fragments %d\n", sblk->fragments); -+ TRACE("Number of ids %d\n", sblk->no_ids); -+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start); -+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start); -+ if (sblk->s_major > 1) -+ TRACE("sblk->fragment_table_start %llx\n", sblk->fragment_table_start); -+ TRACE("sblk->id_table_start %llx\n", sblk->id_table_start); -+ -+ s->s_maxbytes = MAX_LFS_FILESIZE; -+ s->s_flags |= MS_RDONLY; -+ s->s_op = &squashfs_super_ops; -+ -+ msblk->block_cache = squashfs_cache_init("metadata", SQUASHFS_CACHED_BLKS, -+ SQUASHFS_METADATA_SIZE, 0); -+ if (msblk->block_cache == NULL) -+ goto failed_mount; -+ -+ /* Allocate read_page block */ -+ msblk->read_page = vmalloc(sblk->block_size); -+ if (msblk->read_page == NULL) { -+ ERROR("Failed to allocate read_page block\n"); -+ goto failed_mount; -+ } -+ -+ /* Allocate and read id index table */ -+ if (read_id_index_table(s) == 0) -+ goto failed_mount; -+ -+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) -+ goto allocate_root; -+ -+ msblk->fragment_cache = squashfs_cache_init("fragment", -+ SQUASHFS_CACHED_FRAGMENTS, sblk->block_size, 1); -+ if (msblk->fragment_cache == NULL) -+ goto failed_mount; -+ -+ /* Allocate and read fragment index table */ -+ if (msblk->read_fragment_index_table(s) == 0) -+ goto failed_mount; -+ -+ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK) -+ goto allocate_root; -+ -+ /* Allocate and read inode lookup table */ -+ if (read_inode_lookup_table(s) == 0) -+ goto failed_mount; -+ -+ s->s_export_op = &squashfs_export_ops; -+ -+allocate_root: -+ root = new_inode(s); -+ if ((msblk->read_inode)(root, sblk->root_inode) == 0) -+ goto failed_mount; -+ insert_inode_hash(root); -+ -+ s->s_root = d_alloc_root(root); -+ if (s->s_root == NULL) { -+ ERROR("Root inode create failed\n"); -+ iput(root); -+ goto failed_mount; -+ } -+ -+ TRACE("Leaving squashfs_fill_super\n"); -+ return 0; -+ -+failed_mount: -+ kfree(msblk->inode_lookup_table); -+ kfree(msblk->fragment_index); -+ squashfs_cache_delete(msblk->fragment_cache); -+ kfree(msblk->id_table); -+ vfree(msblk->read_page); -+ squashfs_cache_delete(msblk->block_cache); -+ kfree(msblk->fragment_index_2); -+ vfree(msblk->stream.workspace); -+ kfree(s->s_fs_info); -+ s->s_fs_info = NULL; -+ return -EINVAL; -+ -+failure: -+ return -ENOMEM; -+} -+ -+ -+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ TRACE("Entered squashfs_statfs\n"); -+ -+ buf->f_type = SQUASHFS_MAGIC; -+ buf->f_bsize = sblk->block_size; -+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; -+ buf->f_bfree = buf->f_bavail = 0; -+ buf->f_files = sblk->inodes; -+ buf->f_ffree = 0; -+ buf->f_namelen = SQUASHFS_NAME_LEN; -+ -+ return 0; -+} -+ -+ -+static int squashfs_remount(struct super_block *s, int *flags, char *data) -+{ -+ *flags |= MS_RDONLY; -+ return 0; -+} -+ -+ -+static void squashfs_put_super(struct super_block *s) -+{ -+ if (s->s_fs_info) { -+ struct squashfs_sb_info *sbi = s->s_fs_info; -+ squashfs_cache_delete(sbi->block_cache); -+ squashfs_cache_delete(sbi->fragment_cache); -+ vfree(sbi->read_page); -+ kfree(sbi->id_table); -+ kfree(sbi->fragment_index); -+ kfree(sbi->fragment_index_2); -+ kfree(sbi->meta_index); -+ vfree(sbi->stream.workspace); -+ kfree(s->s_fs_info); -+ s->s_fs_info = NULL; -+ } -+} -+ -+ -+static int squashfs_get_sb(struct file_system_type *fs_type, int flags, -+ const char *dev_name, void *data, struct vfsmount *mnt) -+{ -+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, -+ mnt); -+} -+ -+ -+static 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); -+ if (squashfs_inode_cachep == NULL) -+ return -ENOMEM; -+ return 0; -+} -+ -+ -+static void destroy_inodecache(void) -+{ -+ kmem_cache_destroy(squashfs_inode_cachep); -+} -+ -+ -+static int __init init_squashfs_fs(void) -+{ -+ int err = init_inodecache(); -+ if (err) -+ goto out; -+ -+ printk(KERN_INFO "squashfs: version 4.0-CVS (2008/07/27) " -+ "Phillip Lougher\n"); -+ -+ err = register_filesystem(&squashfs_fs_type); -+ if (err) -+ destroy_inodecache(); -+ -+out: -+ return err; -+} -+ -+ -+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; -+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); -+ return ei ? &ei->vfs_inode : NULL; -+} -+ -+ -+static void squashfs_destroy_inode(struct inode *inode) -+{ -+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode)); -+} -+ -+ -+static struct file_system_type squashfs_fs_type = { -+ .owner = THIS_MODULE, -+ .name = "squashfs", -+ .get_sb = squashfs_get_sb, -+ .kill_sb = kill_block_super, -+ .fs_flags = FS_REQUIRES_DEV -+}; -+ -+static 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-CVS, a compressed read-only filesystem"); -+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>"); -+MODULE_LICENSE("GPL"); -diff -uNr a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c ---- a/fs/squashfs/symlink.c 1969-12-31 16:00:00.000000000 -0800 -+++ b/fs/squashfs/symlink.c 2008-08-13 16:14:50.000000000 -0700 -@@ -0,0 +1,85 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * symlink.c -+ */ -+ -+#include <linux/fs.h> -+#include <linux/vfs.h> -+#include <linux/zlib.h> -+#include <linux/buffer_head.h> -+#include <linux/squashfs_fs.h> -+#include <linux/squashfs_fs_sb.h> -+#include <linux/squashfs_fs_i.h> -+ -+#include "squashfs.h" -+ -+static int squashfs_symlink_readpage(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ int index = page->index << PAGE_CACHE_SHIFT; -+ long long block = SQUASHFS_I(inode)->start_block; -+ int offset = SQUASHFS_I(inode)->offset; -+ void *pageaddr = kmap(page); -+ int length, bytes, avail_bytes; -+ -+ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " -+ "%llx, offset %x\n", page->index, -+ SQUASHFS_I(inode)->start_block, -+ SQUASHFS_I(inode)->offset); -+ -+ for (length = 0; length < index; length += bytes) { -+ bytes = squashfs_get_cached_block(inode->i_sb, NULL, block, -+ offset, PAGE_CACHE_SIZE, &block, &offset); -+ if (bytes == 0) { -+ ERROR("Unable to read symbolic link [%llx:%x]\n", -+ block, offset); -+ goto skip_read; -+ } -+ } -+ -+ if (length != index) { -+ ERROR("(squashfs_symlink_readpage) length != index\n"); -+ bytes = 0; -+ goto skip_read; -+ } -+ -+ avail_bytes = min_t(int, i_size_read(inode) - length, PAGE_CACHE_SIZE); -+ -+ bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset, -+ avail_bytes, &block, &offset); -+ if (bytes == 0) -+ ERROR("Unable to read symbolic link [%llx:%x]\n", block, -+ offset); -+ -+skip_read: -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap(page); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ unlock_page(page); -+ -+ return 0; -+} -+ -+ -+const struct address_space_operations squashfs_symlink_aops = { -+ .readpage = squashfs_symlink_readpage -+}; -diff -uNr a/include/linux/squashfs_fs.h b/include/linux/squashfs_fs.h ---- a/include/linux/squashfs_fs.h 1969-12-31 16:00:00.000000000 -0800 -+++ b/include/linux/squashfs_fs.h 2008-08-13 16:16:05.000000000 -0700 -@@ -0,0 +1,949 @@ -+#ifndef SQUASHFS_FS -+#define SQUASHFS_FS -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs.h -+ */ -+ -+#if 0 -+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY -+#endif -+#endif -+ -+#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE -+#define SQUASHFS_MAJOR 4 -+#define SQUASHFS_MINOR 0 -+#define SQUASHFS_MAGIC 0x73717368 -+#define SQUASHFS_MAGIC_SWAP 0x68737173 -+#define SQUASHFS_START 0 -+ -+/* size of metadata (inode and directory) blocks */ -+#define SQUASHFS_METADATA_SIZE 8192 -+#define SQUASHFS_METADATA_LOG 13 -+ -+/* default size of data blocks */ -+#define SQUASHFS_FILE_SIZE 131072 -+#define SQUASHFS_FILE_LOG 17 -+ -+#define SQUASHFS_FILE_MAX_SIZE 1048576 -+ -+/* Max number of uids and gids */ -+#define SQUASHFS_IDS 65536 -+ -+/* Max length of filename (not 255) */ -+#define SQUASHFS_NAME_LEN 256 -+ -+#define SQUASHFS_INVALID ((long long) 0xffffffffffff) -+#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) -+#define SQUASHFS_INVALID_BLK ((long long) -1) -+#define SQUASHFS_USED_BLK ((long long) -2) -+ -+/* Filesystem flags */ -+#define SQUASHFS_NOI 0 -+#define SQUASHFS_NOD 1 -+#define SQUASHFS_CHECK 2 -+#define SQUASHFS_NOF 3 -+#define SQUASHFS_NO_FRAG 4 -+#define SQUASHFS_ALWAYS_FRAG 5 -+#define SQUASHFS_DUPLICATE 6 -+#define SQUASHFS_EXPORT 7 -+ -+#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_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_CHECK) -+ -+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ -+ duplicate_checking, exportable) (noi | (nod << 1) | (check_data << 2) \ -+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ -+ (duplicate_checking << 6) | (exportable << 7)) -+ -+/* Max number of types and file types */ -+#define SQUASHFS_DIR_TYPE 1 -+#define SQUASHFS_FILE_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 -+ -+/* 1.0 filesystem type definitions */ -+#define SQUASHFS_TYPES 5 -+#define SQUASHFS_IPC_TYPE 0 -+ -+/* 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) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ -+ << 16) + (B))) -+ -+/* Compute 32 bit VFS inode number from squashfs inode number */ -+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ -+ ((b) >> 2) + 1)) -+/* XXX */ -+ -+/* Translate between VFS mode and squashfs mode */ -+#define SQUASHFS_MODE(a) ((a) & 0xfff) -+ -+/* 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(long long)) -+ -+/* inode lookup table defines */ -+#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t)) -+ -+#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(long long)) -+ -+/* uid 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(long long)) -+ -+/* cached data constants for filesystem */ -+#define SQUASHFS_CACHED_BLKS 8 -+ -+#define SQUASHFS_MAX_FILE_SIZE_LOG 64 -+ -+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ -+ (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) -+ -+#define SQUASHFS_MARKER_BYTE 0xff -+ -+/* meta index cache */ -+#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) -+#define SQUASHFS_META_ENTRIES 31 -+#define SQUASHFS_META_NUMBER 8 -+#define SQUASHFS_SLOTS 4 -+ -+struct meta_entry { -+ long long 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 -+ */ -+ -+typedef long long squashfs_block_t; -+typedef long long squashfs_inode_t; -+ -+#define COMPRESSION_ZLIB 1 -+ -+struct squashfs_super_block { -+ unsigned int s_magic; -+ unsigned int inodes; -+ unsigned int mkfs_time /* time of filesystem creation */; -+ unsigned int block_size; -+ unsigned int fragments; -+ unsigned short compression; -+ unsigned short block_log; -+ unsigned short flags; -+ unsigned short no_ids; -+ unsigned short s_major; -+ unsigned short s_minor; -+ squashfs_inode_t root_inode; -+ long long bytes_used; -+ long long id_table_start; -+ long long xattr_table_start; -+ long long inode_table_start; -+ long long directory_table_start; -+ long long fragment_table_start; -+ long long lookup_table_start; -+}; -+ -+struct squashfs_dir_index { -+ unsigned int index; -+ unsigned int start_block; -+ unsigned int size; -+ unsigned char name[0]; -+}; -+ -+#define SQUASHFS_BASE_INODE_HEADER \ -+ unsigned short inode_type; \ -+ unsigned short mode; \ -+ unsigned short uid; \ -+ unsigned short guid; \ -+ unsigned int mtime; \ -+ unsigned int inode_number; -+ -+struct squashfs_base_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+}; -+ -+struct squashfs_ipc_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+}; -+ -+struct squashfs_dev_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned int rdev; -+}; -+ -+struct squashfs_symlink_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned int symlink_size; -+ char symlink[0]; -+}; -+ -+struct squashfs_reg_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int start_block; -+ unsigned int fragment; -+ unsigned int offset; -+ unsigned int file_size; -+ unsigned short block_list[0]; -+}; -+ -+struct squashfs_lreg_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ squashfs_block_t start_block; -+ long long file_size; -+ long long sparse; -+ unsigned int nlink; -+ unsigned int fragment; -+ unsigned int offset; -+ unsigned int xattr; -+ unsigned short block_list[0]; -+}; -+ -+struct squashfs_dir_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int start_block; -+ unsigned int nlink; -+ unsigned short file_size; -+ unsigned short offset; -+ unsigned int parent_inode; -+}; -+ -+struct squashfs_ldir_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned int file_size; -+ unsigned int start_block; -+ unsigned int parent_inode; -+ unsigned short i_count; -+ unsigned short offset; -+ struct squashfs_dir_index index[0]; -+}; -+ -+union squashfs_inode_header { -+ struct squashfs_base_inode_header base; -+ struct squashfs_dev_inode_header dev; -+ struct squashfs_symlink_inode_header symlink; -+ struct squashfs_reg_inode_header reg; -+ struct squashfs_lreg_inode_header lreg; -+ struct squashfs_dir_inode_header dir; -+ struct squashfs_ldir_inode_header ldir; -+ struct squashfs_ipc_inode_header ipc; -+}; -+ -+struct squashfs_dir_entry { -+ unsigned short offset; -+ short inode_number; -+ unsigned short type; -+ unsigned short size; -+ char name[0]; -+}; -+ -+struct squashfs_dir_header { -+ unsigned int count; -+ unsigned int start_block; -+ unsigned int inode_number; -+}; -+ -+struct squashfs_fragment_entry { -+ long long start_block; -+ unsigned int size; -+ unsigned int unused; -+}; -+ -+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); -+extern int squashfs_uncompress_init(void); -+extern int squashfs_uncompress_exit(void); -+ -+/* -+ * macros to convert each packed bitfield structure from little endian to big -+ * endian and vice versa. These are needed when creating or using a filesystem -+ * on a machine with different byte ordering to the target architecture. -+ * -+ */ -+ -+#define SQUASHFS_SWAP_START \ -+ int bits;\ -+ int b_pos;\ -+ unsigned long long val;\ -+ unsigned char *s;\ -+ unsigned char *d; -+ -+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ -+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ -+ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ -+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ -+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ -+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ -+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\ -+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ -+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ -+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ -+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ -+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ -+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ -+ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ -+ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ -+ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ -+ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ -+ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ -+ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ -+ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ -+ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\ -+} -+ -+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ -+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->inode_number, d, 64, 32); -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_ipc_inode_header))\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_dev_inode_header)); \ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_symlink_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_reg_inode_header));\ -+ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ -+ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ -+} -+ -+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_lreg_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ -+ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 224, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_dir_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 147, 13);\ -+ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ -+} -+ -+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_ldir_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ -+ SQUASHFS_SWAP((s)->offset, d, 155, 13);\ -+ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ -+ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ -+ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ -+ SQUASHFS_SWAP((s)->index, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->size, d, 64, 8);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ -+ SQUASHFS_SWAP((s)->count, d, 0, 8);\ -+ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ -+ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ -+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ -+ SQUASHFS_SWAP((s)->type, d, 13, 3);\ -+ SQUASHFS_SWAP((s)->size, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ -+ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ -+ SQUASHFS_SWAP((s)->size, d, 64, 32);\ -+} -+ -+#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1) -+ -+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * 2);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ 16)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ -+} -+ -+#define SQUASHFS_SWAP_INTS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * 4);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ 32)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ -+} -+ -+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * 8);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ 64)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ -+} -+ -+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * bits / 8);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ bits)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) -+#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) -+#define SQUASHFS_SWAP_ID_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) -+ -+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+ -+struct squashfs_base_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+} __attribute__ ((packed)); -+ -+struct squashfs_ipc_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int type:4; -+ unsigned int offset:4; -+} __attribute__ ((packed)); -+ -+struct squashfs_dev_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned short rdev; -+} __attribute__ ((packed)); -+ -+struct squashfs_symlink_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_reg_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int mtime; -+ unsigned int start_block; -+ unsigned int file_size:32; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ unsigned int mtime; -+ unsigned int start_block:24; -+} __attribute__ ((packed)); -+ -+union squashfs_inode_header_1 { -+ struct squashfs_base_inode_header_1 base; -+ struct squashfs_dev_inode_header_1 dev; -+ struct squashfs_symlink_inode_header_1 symlink; -+ struct squashfs_reg_inode_header_1 reg; -+ struct squashfs_dir_inode_header_1 dir; -+ struct squashfs_ipc_inode_header_1 ipc; -+}; -+ -+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ -+ SQUASHFS_SWAP((s)->guid, d, 20, 4); -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_ipc_inode_header_1));\ -+ SQUASHFS_SWAP((s)->type, d, 24, 4);\ -+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ -+} -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_dev_inode_header_1));\ -+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_symlink_inode_header_1));\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_reg_inode_header_1));\ -+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_dir_inode_header_1));\ -+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ -+} -+ -+#endif -+ -+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+ -+struct squashfs_dir_index_2 { -+ unsigned int index:27; -+ unsigned int start_block:29; -+ unsigned char size; -+ unsigned char name[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_base_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+} __attribute__ ((packed)); -+ -+struct squashfs_ipc_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+} __attribute__ ((packed)); -+ -+struct squashfs_dev_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned short rdev; -+} __attribute__ ((packed)); -+ -+struct squashfs_symlink_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_reg_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int mtime; -+ unsigned int start_block; -+ unsigned int fragment; -+ unsigned int offset; -+ unsigned int file_size:32; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ unsigned int mtime; -+ unsigned int start_block:24; -+} __attribute__ ((packed)); -+ -+struct squashfs_ldir_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int file_size:27; -+ unsigned int offset:13; -+ unsigned int mtime; -+ unsigned int start_block:24; -+ unsigned int i_count:16; -+ struct squashfs_dir_index_2 index[0]; -+} __attribute__ ((packed)); -+ -+union squashfs_inode_header_2 { -+ struct squashfs_base_inode_header_2 base; -+ struct squashfs_dev_inode_header_2 dev; -+ struct squashfs_symlink_inode_header_2 symlink; -+ struct squashfs_reg_inode_header_2 reg; -+ struct squashfs_dir_inode_header_2 dir; -+ struct squashfs_ldir_inode_header_2 ldir; -+ struct squashfs_ipc_inode_header_2 ipc; -+}; -+ -+struct squashfs_dir_header_2 { -+ unsigned int count:8; -+ unsigned int start_block:24; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_entry_2 { -+ unsigned int offset:13; -+ unsigned int type:3; -+ unsigned int size:8; -+ char name[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_fragment_entry_2 { -+ unsigned int start_block; -+ unsigned int size; -+} __attribute__ ((packed)); -+ -+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ -+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_dev_inode_header_2)); \ -+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_symlink_inode_header_2));\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_reg_inode_header_2));\ -+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_dir_inode_header_2));\ -+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ -+} -+ -+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_ldir_inode_header_2));\ -+ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ -+ SQUASHFS_SWAP((s)->offset, d, 59, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ -+ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ -+ SQUASHFS_SWAP((s)->index, d, 0, 27);\ -+ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ -+ SQUASHFS_SWAP((s)->size, d, 56, 8);\ -+} -+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ -+ SQUASHFS_SWAP((s)->count, d, 0, 8);\ -+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ -+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ -+ SQUASHFS_SWAP((s)->type, d, 13, 3);\ -+ SQUASHFS_SWAP((s)->size, d, 16, 8);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ -+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->size, d, 32, 32);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) -+ -+/* fragment and fragment table defines */ -+#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) -+ -+#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ -+ SQUASHFS_METADATA_SIZE - 1) / \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ -+ sizeof(int)) -+ -+#endif -+ -+#ifdef __KERNEL__ -+ -+/* -+ * macros used to swap each structure entry, taking into account -+ * bitfields and different bitfield placing conventions on differing -+ * architectures -+ */ -+ -+#include <asm/byteorder.h> -+ -+#ifdef __BIG_ENDIAN -+ /* convert from little endian to big endian */ -+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ -+ tbits, b_pos) -+#else -+ /* convert from big endian to little endian */ -+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ -+ tbits, 64 - tbits - b_pos) -+#endif -+ -+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ -+ b_pos = pos % 8;\ -+ val = 0;\ -+ s = (unsigned char *)p + (pos / 8);\ -+ d = ((unsigned char *) &val) + 7;\ -+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ -+ *d-- = *s++;\ -+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ -+} -+ -+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); -+ -+#endif -+#endif -diff -uNr a/include/linux/squashfs_fs_i.h b/include/linux/squashfs_fs_i.h ---- a/include/linux/squashfs_fs_i.h 1969-12-31 16:00:00.000000000 -0800 -+++ b/include/linux/squashfs_fs_i.h 2008-08-13 16:16:05.000000000 -0700 -@@ -0,0 +1,45 @@ -+#ifndef SQUASHFS_FS_I -+#define SQUASHFS_FS_I -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs_i.h -+ */ -+ -+struct squashfs_inode_info { -+ long long start_block; -+ unsigned int offset; -+ union { -+ struct { -+ long long fragment_start_block; -+ unsigned int fragment_size; -+ unsigned int fragment_offset; -+ long long block_list_start; -+ } s1; -+ struct { -+ long long directory_index_start; -+ unsigned int directory_index_offset; -+ unsigned int directory_index_count; -+ unsigned int parent_inode; -+ } s2; -+ } u; -+ struct inode vfs_inode; -+}; -+#endif -diff -uNr a/include/linux/squashfs_fs_sb.h b/include/linux/squashfs_fs_sb.h ---- a/include/linux/squashfs_fs_sb.h 1969-12-31 16:00:00.000000000 -0800 -+++ b/include/linux/squashfs_fs_sb.h 2008-08-13 16:16:05.000000000 -0700 -@@ -0,0 +1,78 @@ -+#ifndef SQUASHFS_FS_SB -+#define SQUASHFS_FS_SB -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ * Phillip Lougher <phillip@lougher.demon.co.uk> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs_sb.h -+ */ -+ -+#include <linux/squashfs_fs.h> -+ -+struct squashfs_cache_entry { -+ long long block; -+ int length; -+ int locked; -+ long long next_index; -+ char pending; -+ char error; -+ int waiting; -+ wait_queue_head_t wait_queue; -+ char *data; -+}; -+ -+struct squashfs_cache { -+ char *name; -+ int entries; -+ int block_size; -+ int next_blk; -+ int waiting; -+ int unused_blks; -+ int use_vmalloc; -+ spinlock_t lock; -+ wait_queue_head_t wait_queue; -+ struct squashfs_cache_entry entry[0]; -+}; -+ -+struct squashfs_sb_info { -+ struct squashfs_super_block sblk; -+ int devblksize; -+ int devblksize_log2; -+ int swap; -+ struct squashfs_cache *block_cache; -+ struct squashfs_cache *fragment_cache; -+ int next_meta_index; -+ unsigned int *id_table; -+ long long *fragment_index; -+ unsigned int *fragment_index_2; -+ char *read_page; -+ struct mutex read_data_mutex; -+ struct mutex read_page_mutex; -+ struct mutex meta_index_mutex; -+ struct meta_index *meta_index; -+ z_stream stream; -+ long long *inode_lookup_table; -+ int (*read_inode)(struct inode *i, squashfs_inode_t \ -+ inode); -+ long long (*read_blocklist)(struct inode *inode, int \ -+ index, int readahead_blks, char *block_list, \ -+ unsigned short **block_p, unsigned int *bsize); -+ int (*read_fragment_index_table)(struct super_block *s); -+}; -+#endif |