summaryrefslogtreecommitdiffstats
path: root/meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch
diff options
context:
space:
mode:
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.patch6727
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 4de9839c76..0000000000
--- a/meta/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch
+++ /dev/null
@@ -1,6727 +0,0 @@
1diff -uNr a/fs/Kconfig b/fs/Kconfig
2--- a/fs/Kconfig 2008-07-28 19:40:31.000000000 -0700
3+++ b/fs/Kconfig 2008-08-13 16:19:56.000000000 -0700
4@@ -1348,6 +1348,56 @@
5
6 If unsure, say N.
7
8+config SQUASHFS
9+ tristate "SquashFS 3.3 - Squashed file system support"
10+ select ZLIB_INFLATE
11+ help
12+ Saying Y here includes support for SquashFS 3.3 (a Compressed
13+ Read-Only File System). Squashfs is a highly compressed read-only
14+ filesystem for Linux. It uses zlib compression to compress both
15+ files, inodes and directories. Inodes in the system are very small
16+ and all blocks are packed to minimise data overhead. Block sizes
17+ greater than 4K are supported up to a maximum of 1 Mbytes (default
18+ block size 128K). SquashFS 3.3 supports 64 bit filesystems and files
19+ (larger than 4GB), full uid/gid information, hard links and timestamps.
20+
21+ Squashfs is intended for general read-only filesystem use, for
22+ archival use (i.e. in cases where a .tar.gz file may be used), and in
23+ embedded systems where low overhead is needed. Further information
24+ and filesystem tools are available from http://squashfs.sourceforge.net.
25+
26+ If you want to compile this as a module ( = code which can be
27+ inserted in and removed from the running kernel whenever you want),
28+ say M here and read <file:Documentation/modules.txt>. The module
29+ will be called squashfs. Note that the root file system (the one
30+ containing the directory /) cannot be compiled as a module.
31+
32+ If unsure, say N.
33+
34+config SQUASHFS_EMBEDDED
35+
36+ bool "Additional option for memory-constrained systems"
37+ depends on SQUASHFS
38+ default n
39+ help
40+ Saying Y here allows you to specify cache size.
41+
42+ If unsure, say N.
43+
44+config SQUASHFS_FRAGMENT_CACHE_SIZE
45+ int "Number of fragments cached" if SQUASHFS_EMBEDDED
46+ depends on SQUASHFS
47+ default "3"
48+ help
49+ By default SquashFS caches the last 3 fragments read from
50+ the filesystem. Increasing this amount may mean SquashFS
51+ has to re-read fragments less often from disk, at the expense
52+ of extra system memory. Decreasing this amount will mean
53+ SquashFS uses less memory at the expense of extra reads from disk.
54+
55+ Note there must be at least one cached fragment. Anything
56+ much more than three will probably not make much difference.
57+
58 config VXFS_FS
59 tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
60 depends on BLOCK
61diff -uNr a/fs/Kconfig.orig b/fs/Kconfig.orig
62--- a/fs/Kconfig.orig 1969-12-31 16:00:00.000000000 -0800
63+++ b/fs/Kconfig.orig 2008-07-28 19:40:31.000000000 -0700
64@@ -0,0 +1,2097 @@
65+#
66+# File system configuration
67+#
68+
69+menu "File systems"
70+
71+if BLOCK
72+
73+config EXT2_FS
74+ tristate "Second extended fs support"
75+ help
76+ Ext2 is a standard Linux file system for hard disks.
77+
78+ To compile this file system support as a module, choose M here: the
79+ module will be called ext2.
80+
81+ If unsure, say Y.
82+
83+config EXT2_FS_XATTR
84+ bool "Ext2 extended attributes"
85+ depends on EXT2_FS
86+ help
87+ Extended attributes are name:value pairs associated with inodes by
88+ the kernel or by users (see the attr(5) manual page, or visit
89+ <http://acl.bestbits.at/> for details).
90+
91+ If unsure, say N.
92+
93+config EXT2_FS_POSIX_ACL
94+ bool "Ext2 POSIX Access Control Lists"
95+ depends on EXT2_FS_XATTR
96+ select FS_POSIX_ACL
97+ help
98+ Posix Access Control Lists (ACLs) support permissions for users and
99+ groups beyond the owner/group/world scheme.
100+
101+ To learn more about Access Control Lists, visit the Posix ACLs for
102+ Linux website <http://acl.bestbits.at/>.
103+
104+ If you don't know what Access Control Lists are, say N
105+
106+config EXT2_FS_SECURITY
107+ bool "Ext2 Security Labels"
108+ depends on EXT2_FS_XATTR
109+ help
110+ Security labels support alternative access control models
111+ implemented by security modules like SELinux. This option
112+ enables an extended attribute handler for file security
113+ labels in the ext2 filesystem.
114+
115+ If you are not using a security module that requires using
116+ extended attributes for file security labels, say N.
117+
118+config EXT2_FS_XIP
119+ bool "Ext2 execute in place support"
120+ depends on EXT2_FS && MMU
121+ help
122+ Execute in place can be used on memory-backed block devices. If you
123+ enable this option, you can select to mount block devices which are
124+ capable of this feature without using the page cache.
125+
126+ If you do not use a block device that is capable of using this,
127+ or if unsure, say N.
128+
129+config FS_XIP
130+# execute in place
131+ bool
132+ depends on EXT2_FS_XIP
133+ default y
134+
135+config EXT3_FS
136+ tristate "Ext3 journalling file system support"
137+ select JBD
138+ help
139+ This is the journalling version of the Second extended file system
140+ (often called ext3), the de facto standard Linux file system
141+ (method to organize files on a storage device) for hard disks.
142+
143+ The journalling code included in this driver means you do not have
144+ to run e2fsck (file system checker) on your file systems after a
145+ crash. The journal keeps track of any changes that were being made
146+ at the time the system crashed, and can ensure that your file system
147+ is consistent without the need for a lengthy check.
148+
149+ Other than adding the journal to the file system, the on-disk format
150+ of ext3 is identical to ext2. It is possible to freely switch
151+ between using the ext3 driver and the ext2 driver, as long as the
152+ file system has been cleanly unmounted, or e2fsck is run on the file
153+ system.
154+
155+ To add a journal on an existing ext2 file system or change the
156+ behavior of ext3 file systems, you can use the tune2fs utility ("man
157+ tune2fs"). To modify attributes of files and directories on ext3
158+ file systems, use chattr ("man chattr"). You need to be using
159+ e2fsprogs version 1.20 or later in order to create ext3 journals
160+ (available at <http://sourceforge.net/projects/e2fsprogs/>).
161+
162+ To compile this file system support as a module, choose M here: the
163+ module will be called ext3.
164+
165+config EXT3_FS_XATTR
166+ bool "Ext3 extended attributes"
167+ depends on EXT3_FS
168+ default y
169+ help
170+ Extended attributes are name:value pairs associated with inodes by
171+ the kernel or by users (see the attr(5) manual page, or visit
172+ <http://acl.bestbits.at/> for details).
173+
174+ If unsure, say N.
175+
176+ You need this for POSIX ACL support on ext3.
177+
178+config EXT3_FS_POSIX_ACL
179+ bool "Ext3 POSIX Access Control Lists"
180+ depends on EXT3_FS_XATTR
181+ select FS_POSIX_ACL
182+ help
183+ Posix Access Control Lists (ACLs) support permissions for users and
184+ groups beyond the owner/group/world scheme.
185+
186+ To learn more about Access Control Lists, visit the Posix ACLs for
187+ Linux website <http://acl.bestbits.at/>.
188+
189+ If you don't know what Access Control Lists are, say N
190+
191+config EXT3_FS_SECURITY
192+ bool "Ext3 Security Labels"
193+ depends on EXT3_FS_XATTR
194+ help
195+ Security labels support alternative access control models
196+ implemented by security modules like SELinux. This option
197+ enables an extended attribute handler for file security
198+ labels in the ext3 filesystem.
199+
200+ If you are not using a security module that requires using
201+ extended attributes for file security labels, say N.
202+
203+config EXT4DEV_FS
204+ tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
205+ depends on EXPERIMENTAL
206+ select JBD2
207+ select CRC16
208+ help
209+ Ext4dev is a predecessor filesystem of the next generation
210+ extended fs ext4, based on ext3 filesystem code. It will be
211+ renamed ext4 fs later, once ext4dev is mature and stabilized.
212+
213+ Unlike the change from ext2 filesystem to ext3 filesystem,
214+ the on-disk format of ext4dev is not the same as ext3 any more:
215+ it is based on extent maps and it supports 48-bit physical block
216+ numbers. These combined on-disk format changes will allow
217+ ext4dev/ext4 to handle more than 16 TB filesystem volumes --
218+ a hard limit that ext3 cannot overcome without changing the
219+ on-disk format.
220+
221+ Other than extent maps and 48-bit block numbers, ext4dev also is
222+ likely to have other new features such as persistent preallocation,
223+ high resolution time stamps, and larger file support etc. These
224+ features will be added to ext4dev gradually.
225+
226+ To compile this file system support as a module, choose M here. The
227+ module will be called ext4dev.
228+
229+ If unsure, say N.
230+
231+config EXT4DEV_FS_XATTR
232+ bool "Ext4dev extended attributes"
233+ depends on EXT4DEV_FS
234+ default y
235+ help
236+ Extended attributes are name:value pairs associated with inodes by
237+ the kernel or by users (see the attr(5) manual page, or visit
238+ <http://acl.bestbits.at/> for details).
239+
240+ If unsure, say N.
241+
242+ You need this for POSIX ACL support on ext4dev/ext4.
243+
244+config EXT4DEV_FS_POSIX_ACL
245+ bool "Ext4dev POSIX Access Control Lists"
246+ depends on EXT4DEV_FS_XATTR
247+ select FS_POSIX_ACL
248+ help
249+ POSIX Access Control Lists (ACLs) support permissions for users and
250+ groups beyond the owner/group/world scheme.
251+
252+ To learn more about Access Control Lists, visit the POSIX ACLs for
253+ Linux website <http://acl.bestbits.at/>.
254+
255+ If you don't know what Access Control Lists are, say N
256+
257+config EXT4DEV_FS_SECURITY
258+ bool "Ext4dev Security Labels"
259+ depends on EXT4DEV_FS_XATTR
260+ help
261+ Security labels support alternative access control models
262+ implemented by security modules like SELinux. This option
263+ enables an extended attribute handler for file security
264+ labels in the ext4dev/ext4 filesystem.
265+
266+ If you are not using a security module that requires using
267+ extended attributes for file security labels, say N.
268+
269+config JBD
270+ tristate
271+ help
272+ This is a generic journalling layer for block devices. It is
273+ currently used by the ext3 and OCFS2 file systems, but it could
274+ also be used to add journal support to other file systems or block
275+ devices such as RAID or LVM.
276+
277+ If you are using the ext3 or OCFS2 file systems, you need to
278+ say Y here. If you are not using ext3 OCFS2 then you will probably
279+ want to say N.
280+
281+ To compile this device as a module, choose M here: the module will be
282+ called jbd. If you are compiling ext3 or OCFS2 into the kernel,
283+ you cannot compile this code as a module.
284+
285+config JBD_DEBUG
286+ bool "JBD (ext3) debugging support"
287+ depends on JBD && DEBUG_FS
288+ help
289+ If you are using the ext3 journaled file system (or potentially any
290+ other file system/device using JBD), this option allows you to
291+ enable debugging output while the system is running, in order to
292+ help track down any problems you are having. By default the
293+ debugging output will be turned off.
294+
295+ If you select Y here, then you will be able to turn on debugging
296+ with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a
297+ number between 1 and 5, the higher the number, the more debugging
298+ output is generated. To turn debugging off again, do
299+ "echo 0 > /sys/kernel/debug/jbd/jbd-debug".
300+
301+config JBD2
302+ tristate
303+ select CRC32
304+ help
305+ This is a generic journaling layer for block devices that support
306+ both 32-bit and 64-bit block numbers. It is currently used by
307+ the ext4dev/ext4 filesystem, but it could also be used to add
308+ journal support to other file systems or block devices such
309+ as RAID or LVM.
310+
311+ If you are using ext4dev/ext4, you need to say Y here. If you are not
312+ using ext4dev/ext4 then you will probably want to say N.
313+
314+ To compile this device as a module, choose M here. The module will be
315+ called jbd2. If you are compiling ext4dev/ext4 into the kernel,
316+ you cannot compile this code as a module.
317+
318+config JBD2_DEBUG
319+ bool "JBD2 (ext4dev/ext4) debugging support"
320+ depends on JBD2 && DEBUG_FS
321+ help
322+ If you are using the ext4dev/ext4 journaled file system (or
323+ potentially any other filesystem/device using JBD2), this option
324+ allows you to enable debugging output while the system is running,
325+ in order to help track down any problems you are having.
326+ By default, the debugging output will be turned off.
327+
328+ If you select Y here, then you will be able to turn on debugging
329+ with "echo N > /sys/kernel/debug/jbd2/jbd2-debug", where N is a
330+ number between 1 and 5. The higher the number, the more debugging
331+ output is generated. To turn debugging off again, do
332+ "echo 0 > /sys/kernel/debug/jbd2/jbd2-debug".
333+
334+config FS_MBCACHE
335+# Meta block cache for Extended Attributes (ext2/ext3/ext4)
336+ tristate
337+ depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4DEV_FS_XATTR
338+ default y if EXT2_FS=y || EXT3_FS=y || EXT4DEV_FS=y
339+ default m if EXT2_FS=m || EXT3_FS=m || EXT4DEV_FS=m
340+
341+config REISERFS_FS
342+ tristate "Reiserfs support"
343+ help
344+ Stores not just filenames but the files themselves in a balanced
345+ tree. Uses journalling.
346+
347+ Balanced trees are more efficient than traditional file system
348+ architectural foundations.
349+
350+ In general, ReiserFS is as fast as ext2, but is very efficient with
351+ large directories and small files. Additional patches are needed
352+ for NFS and quotas, please see <http://www.namesys.com/> for links.
353+
354+ It is more easily extended to have features currently found in
355+ database and keyword search systems than block allocation based file
356+ systems are. The next version will be so extended, and will support
357+ plugins consistent with our motto ``It takes more than a license to
358+ make source code open.''
359+
360+ Read <http://www.namesys.com/> to learn more about reiserfs.
361+
362+ Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com.
363+
364+ If you like it, you can pay us to add new features to it that you
365+ need, buy a support contract, or pay us to port it to another OS.
366+
367+config REISERFS_CHECK
368+ bool "Enable reiserfs debug mode"
369+ depends on REISERFS_FS
370+ help
371+ If you set this to Y, then ReiserFS will perform every check it can
372+ possibly imagine of its internal consistency throughout its
373+ operation. It will also go substantially slower. More than once we
374+ have forgotten that this was on, and then gone despondent over the
375+ latest benchmarks.:-) Use of this option allows our team to go all
376+ out in checking for consistency when debugging without fear of its
377+ effect on end users. If you are on the verge of sending in a bug
378+ report, say Y and you might get a useful error message. Almost
379+ everyone should say N.
380+
381+config REISERFS_PROC_INFO
382+ bool "Stats in /proc/fs/reiserfs"
383+ depends on REISERFS_FS && PROC_FS
384+ help
385+ Create under /proc/fs/reiserfs a hierarchy of files, displaying
386+ various ReiserFS statistics and internal data at the expense of
387+ making your kernel or module slightly larger (+8 KB). This also
388+ increases the amount of kernel memory required for each mount.
389+ Almost everyone but ReiserFS developers and people fine-tuning
390+ reiserfs or tracing problems should say N.
391+
392+config REISERFS_FS_XATTR
393+ bool "ReiserFS extended attributes"
394+ depends on REISERFS_FS
395+ help
396+ Extended attributes are name:value pairs associated with inodes by
397+ the kernel or by users (see the attr(5) manual page, or visit
398+ <http://acl.bestbits.at/> for details).
399+
400+ If unsure, say N.
401+
402+config REISERFS_FS_POSIX_ACL
403+ bool "ReiserFS POSIX Access Control Lists"
404+ depends on REISERFS_FS_XATTR
405+ select FS_POSIX_ACL
406+ help
407+ Posix Access Control Lists (ACLs) support permissions for users and
408+ groups beyond the owner/group/world scheme.
409+
410+ To learn more about Access Control Lists, visit the Posix ACLs for
411+ Linux website <http://acl.bestbits.at/>.
412+
413+ If you don't know what Access Control Lists are, say N
414+
415+config REISERFS_FS_SECURITY
416+ bool "ReiserFS Security Labels"
417+ depends on REISERFS_FS_XATTR
418+ help
419+ Security labels support alternative access control models
420+ implemented by security modules like SELinux. This option
421+ enables an extended attribute handler for file security
422+ labels in the ReiserFS filesystem.
423+
424+ If you are not using a security module that requires using
425+ extended attributes for file security labels, say N.
426+
427+config JFS_FS
428+ tristate "JFS filesystem support"
429+ select NLS
430+ help
431+ This is a port of IBM's Journaled Filesystem . More information is
432+ available in the file <file:Documentation/filesystems/jfs.txt>.
433+
434+ If you do not intend to use the JFS filesystem, say N.
435+
436+config JFS_POSIX_ACL
437+ bool "JFS POSIX Access Control Lists"
438+ depends on JFS_FS
439+ select FS_POSIX_ACL
440+ help
441+ Posix Access Control Lists (ACLs) support permissions for users and
442+ groups beyond the owner/group/world scheme.
443+
444+ To learn more about Access Control Lists, visit the Posix ACLs for
445+ Linux website <http://acl.bestbits.at/>.
446+
447+ If you don't know what Access Control Lists are, say N
448+
449+config JFS_SECURITY
450+ bool "JFS Security Labels"
451+ depends on JFS_FS
452+ help
453+ Security labels support alternative access control models
454+ implemented by security modules like SELinux. This option
455+ enables an extended attribute handler for file security
456+ labels in the jfs filesystem.
457+
458+ If you are not using a security module that requires using
459+ extended attributes for file security labels, say N.
460+
461+config JFS_DEBUG
462+ bool "JFS debugging"
463+ depends on JFS_FS
464+ help
465+ If you are experiencing any problems with the JFS filesystem, say
466+ Y here. This will result in additional debugging messages to be
467+ written to the system log. Under normal circumstances, this
468+ results in very little overhead.
469+
470+config JFS_STATISTICS
471+ bool "JFS statistics"
472+ depends on JFS_FS
473+ help
474+ Enabling this option will cause statistics from the JFS file system
475+ to be made available to the user in the /proc/fs/jfs/ directory.
476+
477+config FS_POSIX_ACL
478+# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/nfs4)
479+#
480+# NOTE: you can implement Posix ACLs without these helpers (XFS does).
481+# Never use this symbol for ifdefs.
482+#
483+ bool
484+ default n
485+
486+source "fs/xfs/Kconfig"
487+source "fs/gfs2/Kconfig"
488+
489+config OCFS2_FS
490+ tristate "OCFS2 file system support"
491+ depends on NET && SYSFS
492+ select CONFIGFS_FS
493+ select JBD
494+ select CRC32
495+ help
496+ OCFS2 is a general purpose extent based shared disk cluster file
497+ system with many similarities to ext3. It supports 64 bit inode
498+ numbers, and has automatically extending metadata groups which may
499+ also make it attractive for non-clustered use.
500+
501+ You'll want to install the ocfs2-tools package in order to at least
502+ get "mount.ocfs2".
503+
504+ Project web page: http://oss.oracle.com/projects/ocfs2
505+ Tools web page: http://oss.oracle.com/projects/ocfs2-tools
506+ OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
507+
508+ For more information on OCFS2, see the file
509+ <file:Documentation/filesystems/ocfs2.txt>.
510+
511+config OCFS2_FS_O2CB
512+ tristate "O2CB Kernelspace Clustering"
513+ depends on OCFS2_FS
514+ default y
515+ help
516+ OCFS2 includes a simple kernelspace clustering package, the OCFS2
517+ Cluster Base. It only requires a very small userspace component
518+ to configure it. This comes with the standard ocfs2-tools package.
519+ O2CB is limited to maintaining a cluster for OCFS2 file systems.
520+ It cannot manage any other cluster applications.
521+
522+ It is always safe to say Y here, as the clustering method is
523+ run-time selectable.
524+
525+config OCFS2_FS_USERSPACE_CLUSTER
526+ tristate "OCFS2 Userspace Clustering"
527+ depends on OCFS2_FS && DLM
528+ default y
529+ help
530+ This option will allow OCFS2 to use userspace clustering services
531+ in conjunction with the DLM in fs/dlm. If you are using a
532+ userspace cluster manager, say Y here.
533+
534+ It is safe to say Y, as the clustering method is run-time
535+ selectable.
536+
537+config OCFS2_FS_STATS
538+ bool "OCFS2 statistics"
539+ depends on OCFS2_FS
540+ default y
541+ help
542+ This option allows some fs statistics to be captured. Enabling
543+ this option may increase the memory consumption.
544+
545+config OCFS2_DEBUG_MASKLOG
546+ bool "OCFS2 logging support"
547+ depends on OCFS2_FS
548+ default y
549+ help
550+ The ocfs2 filesystem has an extensive logging system. The system
551+ allows selection of events to log via files in /sys/o2cb/logmask/.
552+ This option will enlarge your kernel, but it allows debugging of
553+ ocfs2 filesystem issues.
554+
555+config OCFS2_DEBUG_FS
556+ bool "OCFS2 expensive checks"
557+ depends on OCFS2_FS
558+ default n
559+ help
560+ This option will enable expensive consistency checks. Enable
561+ this option for debugging only as it is likely to decrease
562+ performance of the filesystem.
563+
564+endif # BLOCK
565+
566+config DNOTIFY
567+ bool "Dnotify support"
568+ default y
569+ help
570+ Dnotify is a directory-based per-fd file change notification system
571+ that uses signals to communicate events to user-space. There exist
572+ superior alternatives, but some applications may still rely on
573+ dnotify.
574+
575+ If unsure, say Y.
576+
577+config INOTIFY
578+ bool "Inotify file change notification support"
579+ default y
580+ ---help---
581+ Say Y here to enable inotify support. Inotify is a file change
582+ notification system and a replacement for dnotify. Inotify fixes
583+ numerous shortcomings in dnotify and introduces several new features
584+ including multiple file events, one-shot support, and unmount
585+ notification.
586+
587+ For more information, see <file:Documentation/filesystems/inotify.txt>
588+
589+ If unsure, say Y.
590+
591+config INOTIFY_USER
592+ bool "Inotify support for userspace"
593+ depends on INOTIFY
594+ default y
595+ ---help---
596+ Say Y here to enable inotify support for userspace, including the
597+ associated system calls. Inotify allows monitoring of both files and
598+ directories via a single open fd. Events are read from the file
599+ descriptor, which is also select()- and poll()-able.
600+
601+ For more information, see <file:Documentation/filesystems/inotify.txt>
602+
603+ If unsure, say Y.
604+
605+config QUOTA
606+ bool "Quota support"
607+ help
608+ If you say Y here, you will be able to set per user limits for disk
609+ usage (also called disk quotas). Currently, it works for the
610+ ext2, ext3, and reiserfs file system. ext3 also supports journalled
611+ quotas for which you don't need to run quotacheck(8) after an unclean
612+ shutdown.
613+ For further details, read the Quota mini-HOWTO, available from
614+ <http://www.tldp.org/docs.html#howto>, or the documentation provided
615+ with the quota tools. Probably the quota support is only useful for
616+ multi user systems. If unsure, say N.
617+
618+config QUOTA_NETLINK_INTERFACE
619+ bool "Report quota messages through netlink interface"
620+ depends on QUOTA && NET
621+ help
622+ If you say Y here, quota warnings (about exceeding softlimit, reaching
623+ hardlimit, etc.) will be reported through netlink interface. If unsure,
624+ say Y.
625+
626+config PRINT_QUOTA_WARNING
627+ bool "Print quota warnings to console (OBSOLETE)"
628+ depends on QUOTA
629+ default y
630+ help
631+ If you say Y here, quota warnings (about exceeding softlimit, reaching
632+ hardlimit, etc.) will be printed to the process' controlling terminal.
633+ Note that this behavior is currently deprecated and may go away in
634+ future. Please use notification via netlink socket instead.
635+
636+config QFMT_V1
637+ tristate "Old quota format support"
638+ depends on QUOTA
639+ help
640+ This quota format was (is) used by kernels earlier than 2.4.22. If
641+ you have quota working and you don't want to convert to new quota
642+ format say Y here.
643+
644+config QFMT_V2
645+ tristate "Quota format v2 support"
646+ depends on QUOTA
647+ help
648+ This quota format allows using quotas with 32-bit UIDs/GIDs. If you
649+ need this functionality say Y here.
650+
651+config QUOTACTL
652+ bool
653+ depends on XFS_QUOTA || QUOTA
654+ default y
655+
656+config AUTOFS_FS
657+ tristate "Kernel automounter support"
658+ help
659+ The automounter is a tool to automatically mount remote file systems
660+ on demand. This implementation is partially kernel-based to reduce
661+ overhead in the already-mounted case; this is unlike the BSD
662+ automounter (amd), which is a pure user space daemon.
663+
664+ To use the automounter you need the user-space tools from the autofs
665+ package; you can find the location in <file:Documentation/Changes>.
666+ You also want to answer Y to "NFS file system support", below.
667+
668+ If you want to use the newer version of the automounter with more
669+ features, say N here and say Y to "Kernel automounter v4 support",
670+ below.
671+
672+ To compile this support as a module, choose M here: the module will be
673+ called autofs.
674+
675+ If you are not a part of a fairly large, distributed network, you
676+ probably do not need an automounter, and can say N here.
677+
678+config AUTOFS4_FS
679+ tristate "Kernel automounter version 4 support (also supports v3)"
680+ help
681+ The automounter is a tool to automatically mount remote file systems
682+ on demand. This implementation is partially kernel-based to reduce
683+ overhead in the already-mounted case; this is unlike the BSD
684+ automounter (amd), which is a pure user space daemon.
685+
686+ To use the automounter you need the user-space tools from
687+ <ftp://ftp.kernel.org/pub/linux/daemons/autofs/v4/>; you also
688+ want to answer Y to "NFS file system support", below.
689+
690+ To compile this support as a module, choose M here: the module will be
691+ called autofs4. You will need to add "alias autofs autofs4" to your
692+ modules configuration file.
693+
694+ If you are not a part of a fairly large, distributed network or
695+ don't have a laptop which needs to dynamically reconfigure to the
696+ local network, you probably do not need an automounter, and can say
697+ N here.
698+
699+config FUSE_FS
700+ tristate "Filesystem in Userspace support"
701+ help
702+ With FUSE it is possible to implement a fully functional filesystem
703+ in a userspace program.
704+
705+ There's also companion library: libfuse. This library along with
706+ utilities is available from the FUSE homepage:
707+ <http://fuse.sourceforge.net/>
708+
709+ See <file:Documentation/filesystems/fuse.txt> for more information.
710+ See <file:Documentation/Changes> for needed library/utility version.
711+
712+ If you want to develop a userspace FS, or if you want to use
713+ a filesystem based on FUSE, answer Y or M.
714+
715+config GENERIC_ACL
716+ bool
717+ select FS_POSIX_ACL
718+
719+if BLOCK
720+menu "CD-ROM/DVD Filesystems"
721+
722+config ISO9660_FS
723+ tristate "ISO 9660 CDROM file system support"
724+ help
725+ This is the standard file system used on CD-ROMs. It was previously
726+ known as "High Sierra File System" and is called "hsfs" on other
727+ Unix systems. The so-called Rock-Ridge extensions which allow for
728+ long Unix filenames and symbolic links are also supported by this
729+ driver. If you have a CD-ROM drive and want to do more with it than
730+ just listen to audio CDs and watch its LEDs, say Y (and read
731+ <file:Documentation/filesystems/isofs.txt> and the CD-ROM-HOWTO,
732+ available from <http://www.tldp.org/docs.html#howto>), thereby
733+ enlarging your kernel by about 27 KB; otherwise say N.
734+
735+ To compile this file system support as a module, choose M here: the
736+ module will be called isofs.
737+
738+config JOLIET
739+ bool "Microsoft Joliet CDROM extensions"
740+ depends on ISO9660_FS
741+ select NLS
742+ help
743+ Joliet is a Microsoft extension for the ISO 9660 CD-ROM file system
744+ which allows for long filenames in unicode format (unicode is the
745+ new 16 bit character code, successor to ASCII, which encodes the
746+ characters of almost all languages of the world; see
747+ <http://www.unicode.org/> for more information). Say Y here if you
748+ want to be able to read Joliet CD-ROMs under Linux.
749+
750+config ZISOFS
751+ bool "Transparent decompression extension"
752+ depends on ISO9660_FS
753+ select ZLIB_INFLATE
754+ help
755+ This is a Linux-specific extension to RockRidge which lets you store
756+ data in compressed form on a CD-ROM and have it transparently
757+ decompressed when the CD-ROM is accessed. See
758+ <http://www.kernel.org/pub/linux/utils/fs/zisofs/> for the tools
759+ necessary to create such a filesystem. Say Y here if you want to be
760+ able to read such compressed CD-ROMs.
761+
762+config UDF_FS
763+ tristate "UDF file system support"
764+ select CRC_ITU_T
765+ help
766+ This is the new file system used on some CD-ROMs and DVDs. Say Y if
767+ you intend to mount DVD discs or CDRW's written in packet mode, or
768+ if written to by other UDF utilities, such as DirectCD.
769+ Please read <file:Documentation/filesystems/udf.txt>.
770+
771+ To compile this file system support as a module, choose M here: the
772+ module will be called udf.
773+
774+ If unsure, say N.
775+
776+config UDF_NLS
777+ bool
778+ default y
779+ depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y)
780+
781+endmenu
782+endif # BLOCK
783+
784+if BLOCK
785+menu "DOS/FAT/NT Filesystems"
786+
787+config FAT_FS
788+ tristate
789+ select NLS
790+ help
791+ If you want to use one of the FAT-based file systems (the MS-DOS and
792+ VFAT (Windows 95) file systems), then you must say Y or M here
793+ to include FAT support. You will then be able to mount partitions or
794+ diskettes with FAT-based file systems and transparently access the
795+ files on them, i.e. MSDOS files will look and behave just like all
796+ other Unix files.
797+
798+ This FAT support is not a file system in itself, it only provides
799+ the foundation for the other file systems. You will have to say Y or
800+ M to at least one of "MSDOS fs support" or "VFAT fs support" in
801+ order to make use of it.
802+
803+ Another way to read and write MSDOS floppies and hard drive
804+ partitions from within Linux (but not transparently) is with the
805+ mtools ("man mtools") program suite. You don't need to say Y here in
806+ order to do that.
807+
808+ If you need to move large files on floppies between a DOS and a
809+ Linux box, say Y here, mount the floppy under Linux with an MSDOS
810+ file system and use GNU tar's M option. GNU tar is a program
811+ available for Unix and DOS ("man tar" or "info tar").
812+
813+ The FAT support will enlarge your kernel by about 37 KB. If unsure,
814+ say Y.
815+
816+ To compile this as a module, choose M here: the module will be called
817+ fat. Note that if you compile the FAT support as a module, you
818+ cannot compile any of the FAT-based file systems into the kernel
819+ -- they will have to be modules as well.
820+
821+config MSDOS_FS
822+ tristate "MSDOS fs support"
823+ select FAT_FS
824+ help
825+ This allows you to mount MSDOS partitions of your hard drive (unless
826+ they are compressed; to access compressed MSDOS partitions under
827+ Linux, you can either use the DOS emulator DOSEMU, described in the
828+ DOSEMU-HOWTO, available from
829+ <http://www.tldp.org/docs.html#howto>, or try dmsdosfs in
830+ <ftp://ibiblio.org/pub/Linux/system/filesystems/dosfs/>. If you
831+ intend to use dosemu with a non-compressed MSDOS partition, say Y
832+ here) and MSDOS floppies. This means that file access becomes
833+ transparent, i.e. the MSDOS files look and behave just like all
834+ other Unix files.
835+
836+ If you have Windows 95 or Windows NT installed on your MSDOS
837+ partitions, you should use the VFAT file system (say Y to "VFAT fs
838+ support" below), or you will not be able to see the long filenames
839+ generated by Windows 95 / Windows NT.
840+
841+ This option will enlarge your kernel by about 7 KB. If unsure,
842+ answer Y. This will only work if you said Y to "DOS FAT fs support"
843+ as well. To compile this as a module, choose M here: the module will
844+ be called msdos.
845+
846+config VFAT_FS
847+ tristate "VFAT (Windows-95) fs support"
848+ select FAT_FS
849+ help
850+ This option provides support for normal Windows file systems with
851+ long filenames. That includes non-compressed FAT-based file systems
852+ used by Windows 95, Windows 98, Windows NT 4.0, and the Unix
853+ programs from the mtools package.
854+
855+ The VFAT support enlarges your kernel by about 10 KB and it only
856+ works if you said Y to the "DOS FAT fs support" above. Please read
857+ the file <file:Documentation/filesystems/vfat.txt> for details. If
858+ unsure, say Y.
859+
860+ To compile this as a module, choose M here: the module will be called
861+ vfat.
862+
863+config FAT_DEFAULT_CODEPAGE
864+ int "Default codepage for FAT"
865+ depends on MSDOS_FS || VFAT_FS
866+ default 437
867+ help
868+ This option should be set to the codepage of your FAT filesystems.
869+ It can be overridden with the "codepage" mount option.
870+ See <file:Documentation/filesystems/vfat.txt> for more information.
871+
872+config FAT_DEFAULT_IOCHARSET
873+ string "Default iocharset for FAT"
874+ depends on VFAT_FS
875+ default "iso8859-1"
876+ help
877+ Set this to the default input/output character set you'd
878+ like FAT to use. It should probably match the character set
879+ that most of your FAT filesystems use, and can be overridden
880+ with the "iocharset" mount option for FAT filesystems.
881+ Note that "utf8" is not recommended for FAT filesystems.
882+ If unsure, you shouldn't set "utf8" here.
883+ See <file:Documentation/filesystems/vfat.txt> for more information.
884+
885+config NTFS_FS
886+ tristate "NTFS file system support"
887+ select NLS
888+ help
889+ NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003.
890+
891+ Saying Y or M here enables read support. There is partial, but
892+ safe, write support available. For write support you must also
893+ say Y to "NTFS write support" below.
894+
895+ There are also a number of user-space tools available, called
896+ ntfsprogs. These include ntfsundelete and ntfsresize, that work
897+ without NTFS support enabled in the kernel.
898+
899+ This is a rewrite from scratch of Linux NTFS support and replaced
900+ the old NTFS code starting with Linux 2.5.11. A backport to
901+ the Linux 2.4 kernel series is separately available as a patch
902+ from the project web site.
903+
904+ For more information see <file:Documentation/filesystems/ntfs.txt>
905+ and <http://www.linux-ntfs.org/>.
906+
907+ To compile this file system support as a module, choose M here: the
908+ module will be called ntfs.
909+
910+ If you are not using Windows NT, 2000, XP or 2003 in addition to
911+ Linux on your computer it is safe to say N.
912+
913+config NTFS_DEBUG
914+ bool "NTFS debugging support"
915+ depends on NTFS_FS
916+ help
917+ If you are experiencing any problems with the NTFS file system, say
918+ Y here. This will result in additional consistency checks to be
919+ performed by the driver as well as additional debugging messages to
920+ be written to the system log. Note that debugging messages are
921+ disabled by default. To enable them, supply the option debug_msgs=1
922+ at the kernel command line when booting the kernel or as an option
923+ to insmod when loading the ntfs module. Once the driver is active,
924+ you can enable debugging messages by doing (as root):
925+ echo 1 > /proc/sys/fs/ntfs-debug
926+ Replacing the "1" with "0" would disable debug messages.
927+
928+ If you leave debugging messages disabled, this results in little
929+ overhead, but enabling debug messages results in very significant
930+ slowdown of the system.
931+
932+ When reporting bugs, please try to have available a full dump of
933+ debugging messages while the misbehaviour was occurring.
934+
935+config NTFS_RW
936+ bool "NTFS write support"
937+ depends on NTFS_FS
938+ help
939+ This enables the partial, but safe, write support in the NTFS driver.
940+
941+ The only supported operation is overwriting existing files, without
942+ changing the file length. No file or directory creation, deletion or
943+ renaming is possible. Note only non-resident files can be written to
944+ so you may find that some very small files (<500 bytes or so) cannot
945+ be written to.
946+
947+ While we cannot guarantee that it will not damage any data, we have
948+ so far not received a single report where the driver would have
949+ damaged someones data so we assume it is perfectly safe to use.
950+
951+ Note: While write support is safe in this version (a rewrite from
952+ scratch of the NTFS support), it should be noted that the old NTFS
953+ write support, included in Linux 2.5.10 and before (since 1997),
954+ is not safe.
955+
956+ This is currently useful with TopologiLinux. TopologiLinux is run
957+ on top of any DOS/Microsoft Windows system without partitioning your
958+ hard disk. Unlike other Linux distributions TopologiLinux does not
959+ need its own partition. For more information see
960+ <http://topologi-linux.sourceforge.net/>
961+
962+ It is perfectly safe to say N here.
963+
964+endmenu
965+endif # BLOCK
966+
967+menu "Pseudo filesystems"
968+
969+source "fs/proc/Kconfig"
970+
971+config SYSFS
972+ bool "sysfs file system support" if EMBEDDED
973+ default y
974+ help
975+ The sysfs filesystem is a virtual filesystem that the kernel uses to
976+ export internal kernel objects, their attributes, and their
977+ relationships to one another.
978+
979+ Users can use sysfs to ascertain useful information about the running
980+ kernel, such as the devices the kernel has discovered on each bus and
981+ which driver each is bound to. sysfs can also be used to tune devices
982+ and other kernel subsystems.
983+
984+ Some system agents rely on the information in sysfs to operate.
985+ /sbin/hotplug uses device and object attributes in sysfs to assist in
986+ delegating policy decisions, like persistently naming devices.
987+
988+ sysfs is currently used by the block subsystem to mount the root
989+ partition. If sysfs is disabled you must specify the boot device on
990+ the kernel boot command line via its major and minor numbers. For
991+ example, "root=03:01" for /dev/hda1.
992+
993+ Designers of embedded systems may wish to say N here to conserve space.
994+
995+config TMPFS
996+ bool "Virtual memory file system support (former shm fs)"
997+ help
998+ Tmpfs is a file system which keeps all files in virtual memory.
999+
1000+ Everything in tmpfs is temporary in the sense that no files will be
1001+ created on your hard drive. The files live in memory and swap
1002+ space. If you unmount a tmpfs instance, everything stored therein is
1003+ lost.
1004+
1005+ See <file:Documentation/filesystems/tmpfs.txt> for details.
1006+
1007+config TMPFS_POSIX_ACL
1008+ bool "Tmpfs POSIX Access Control Lists"
1009+ depends on TMPFS
1010+ select GENERIC_ACL
1011+ help
1012+ POSIX Access Control Lists (ACLs) support permissions for users and
1013+ groups beyond the owner/group/world scheme.
1014+
1015+ To learn more about Access Control Lists, visit the POSIX ACLs for
1016+ Linux website <http://acl.bestbits.at/>.
1017+
1018+ If you don't know what Access Control Lists are, say N.
1019+
1020+config HUGETLBFS
1021+ bool "HugeTLB file system support"
1022+ depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \
1023+ (S390 && 64BIT) || BROKEN
1024+ help
1025+ hugetlbfs is a filesystem backing for HugeTLB pages, based on
1026+ ramfs. For architectures that support it, say Y here and read
1027+ <file:Documentation/vm/hugetlbpage.txt> for details.
1028+
1029+ If unsure, say N.
1030+
1031+config HUGETLB_PAGE
1032+ def_bool HUGETLBFS
1033+
1034+config CONFIGFS_FS
1035+ tristate "Userspace-driven configuration filesystem"
1036+ depends on SYSFS
1037+ help
1038+ configfs is a ram-based filesystem that provides the converse
1039+ of sysfs's functionality. Where sysfs is a filesystem-based
1040+ view of kernel objects, configfs is a filesystem-based manager
1041+ of kernel objects, or config_items.
1042+
1043+ Both sysfs and configfs can and should exist together on the
1044+ same system. One is not a replacement for the other.
1045+
1046+endmenu
1047+
1048+menu "Miscellaneous filesystems"
1049+
1050+config ADFS_FS
1051+ tristate "ADFS file system support (EXPERIMENTAL)"
1052+ depends on BLOCK && EXPERIMENTAL
1053+ help
1054+ The Acorn Disc Filing System is the standard file system of the
1055+ RiscOS operating system which runs on Acorn's ARM-based Risc PC
1056+ systems and the Acorn Archimedes range of machines. If you say Y
1057+ here, Linux will be able to read from ADFS partitions on hard drives
1058+ and from ADFS-formatted floppy discs. If you also want to be able to
1059+ write to those devices, say Y to "ADFS write support" below.
1060+
1061+ The ADFS partition should be the first partition (i.e.,
1062+ /dev/[hs]d?1) on each of your drives. Please read the file
1063+ <file:Documentation/filesystems/adfs.txt> for further details.
1064+
1065+ To compile this code as a module, choose M here: the module will be
1066+ called adfs.
1067+
1068+ If unsure, say N.
1069+
1070+config ADFS_FS_RW
1071+ bool "ADFS write support (DANGEROUS)"
1072+ depends on ADFS_FS
1073+ help
1074+ If you say Y here, you will be able to write to ADFS partitions on
1075+ hard drives and ADFS-formatted floppy disks. This is experimental
1076+ codes, so if you're unsure, say N.
1077+
1078+config AFFS_FS
1079+ tristate "Amiga FFS file system support (EXPERIMENTAL)"
1080+ depends on BLOCK && EXPERIMENTAL
1081+ help
1082+ The Fast File System (FFS) is the common file system used on hard
1083+ disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y
1084+ if you want to be able to read and write files from and to an Amiga
1085+ FFS partition on your hard drive. Amiga floppies however cannot be
1086+ read with this driver due to an incompatibility of the floppy
1087+ controller used in an Amiga and the standard floppy controller in
1088+ PCs and workstations. Read <file:Documentation/filesystems/affs.txt>
1089+ and <file:fs/affs/Changes>.
1090+
1091+ With this driver you can also mount disk files used by Bernd
1092+ Schmidt's Un*X Amiga Emulator
1093+ (<http://www.freiburg.linux.de/~uae/>).
1094+ If you want to do this, you will also need to say Y or M to "Loop
1095+ device support", above.
1096+
1097+ To compile this file system support as a module, choose M here: the
1098+ module will be called affs. If unsure, say N.
1099+
1100+config ECRYPT_FS
1101+ tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
1102+ depends on EXPERIMENTAL && KEYS && CRYPTO && NET
1103+ help
1104+ Encrypted filesystem that operates on the VFS layer. See
1105+ <file:Documentation/filesystems/ecryptfs.txt> to learn more about
1106+ eCryptfs. Userspace components are required and can be
1107+ obtained from <http://ecryptfs.sf.net>.
1108+
1109+ To compile this file system support as a module, choose M here: the
1110+ module will be called ecryptfs.
1111+
1112+config HFS_FS
1113+ tristate "Apple Macintosh file system support (EXPERIMENTAL)"
1114+ depends on BLOCK && EXPERIMENTAL
1115+ select NLS
1116+ help
1117+ If you say Y here, you will be able to mount Macintosh-formatted
1118+ floppy disks and hard drive partitions with full read-write access.
1119+ Please read <file:Documentation/filesystems/hfs.txt> to learn about
1120+ the available mount options.
1121+
1122+ To compile this file system support as a module, choose M here: the
1123+ module will be called hfs.
1124+
1125+config HFSPLUS_FS
1126+ tristate "Apple Extended HFS file system support"
1127+ depends on BLOCK
1128+ select NLS
1129+ select NLS_UTF8
1130+ help
1131+ If you say Y here, you will be able to mount extended format
1132+ Macintosh-formatted hard drive partitions with full read-write access.
1133+
1134+ This file system is often called HFS+ and was introduced with
1135+ MacOS 8. It includes all Mac specific filesystem data such as
1136+ data forks and creator codes, but it also has several UNIX
1137+ style features such as file ownership and permissions.
1138+
1139+config BEFS_FS
1140+ tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)"
1141+ depends on BLOCK && EXPERIMENTAL
1142+ select NLS
1143+ help
1144+ The BeOS File System (BeFS) is the native file system of Be, Inc's
1145+ BeOS. Notable features include support for arbitrary attributes
1146+ on files and directories, and database-like indices on selected
1147+ attributes. (Also note that this driver doesn't make those features
1148+ available at this time). It is a 64 bit filesystem, so it supports
1149+ extremely large volumes and files.
1150+
1151+ If you use this filesystem, you should also say Y to at least one
1152+ of the NLS (native language support) options below.
1153+
1154+ If you don't know what this is about, say N.
1155+
1156+ To compile this as a module, choose M here: the module will be
1157+ called befs.
1158+
1159+config BEFS_DEBUG
1160+ bool "Debug BeFS"
1161+ depends on BEFS_FS
1162+ help
1163+ If you say Y here, you can use the 'debug' mount option to enable
1164+ debugging output from the driver.
1165+
1166+config BFS_FS
1167+ tristate "BFS file system support (EXPERIMENTAL)"
1168+ depends on BLOCK && EXPERIMENTAL
1169+ help
1170+ Boot File System (BFS) is a file system used under SCO UnixWare to
1171+ allow the bootloader access to the kernel image and other important
1172+ files during the boot process. It is usually mounted under /stand
1173+ and corresponds to the slice marked as "STAND" in the UnixWare
1174+ partition. You should say Y if you want to read or write the files
1175+ on your /stand slice from within Linux. You then also need to say Y
1176+ to "UnixWare slices support", below. More information about the BFS
1177+ file system is contained in the file
1178+ <file:Documentation/filesystems/bfs.txt>.
1179+
1180+ If you don't know what this is about, say N.
1181+
1182+ To compile this as a module, choose M here: the module will be called
1183+ bfs. Note that the file system of your root partition (the one
1184+ containing the directory /) cannot be compiled as a module.
1185+
1186+
1187+
1188+config EFS_FS
1189+ tristate "EFS file system support (read only) (EXPERIMENTAL)"
1190+ depends on BLOCK && EXPERIMENTAL
1191+ help
1192+ EFS is an older file system used for non-ISO9660 CD-ROMs and hard
1193+ disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer
1194+ uses the XFS file system for hard disk partitions however).
1195+
1196+ This implementation only offers read-only access. If you don't know
1197+ what all this is about, it's safe to say N. For more information
1198+ about EFS see its home page at <http://aeschi.ch.eu.org/efs/>.
1199+
1200+ To compile the EFS file system support as a module, choose M here: the
1201+ module will be called efs.
1202+
1203+config JFFS2_FS
1204+ tristate "Journalling Flash File System v2 (JFFS2) support"
1205+ select CRC32
1206+ depends on MTD
1207+ help
1208+ JFFS2 is the second generation of the Journalling Flash File System
1209+ for use on diskless embedded devices. It provides improved wear
1210+ levelling, compression and support for hard links. You cannot use
1211+ this on normal block devices, only on 'MTD' devices.
1212+
1213+ Further information on the design and implementation of JFFS2 is
1214+ available at <http://sources.redhat.com/jffs2/>.
1215+
1216+config JFFS2_FS_DEBUG
1217+ int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
1218+ depends on JFFS2_FS
1219+ default "0"
1220+ help
1221+ This controls the amount of debugging messages produced by the JFFS2
1222+ code. Set it to zero for use in production systems. For evaluation,
1223+ testing and debugging, it's advisable to set it to one. This will
1224+ enable a few assertions and will print debugging messages at the
1225+ KERN_DEBUG loglevel, where they won't normally be visible. Level 2
1226+ is unlikely to be useful - it enables extra debugging in certain
1227+ areas which at one point needed debugging, but when the bugs were
1228+ located and fixed, the detailed messages were relegated to level 2.
1229+
1230+ If reporting bugs, please try to have available a full dump of the
1231+ messages at debug level 1 while the misbehaviour was occurring.
1232+
1233+config JFFS2_FS_WRITEBUFFER
1234+ bool "JFFS2 write-buffering support"
1235+ depends on JFFS2_FS
1236+ default y
1237+ help
1238+ This enables the write-buffering support in JFFS2.
1239+
1240+ This functionality is required to support JFFS2 on the following
1241+ types of flash devices:
1242+ - NAND flash
1243+ - NOR flash with transparent ECC
1244+ - DataFlash
1245+
1246+config JFFS2_FS_WBUF_VERIFY
1247+ bool "Verify JFFS2 write-buffer reads"
1248+ depends on JFFS2_FS_WRITEBUFFER
1249+ default n
1250+ help
1251+ This causes JFFS2 to read back every page written through the
1252+ write-buffer, and check for errors.
1253+
1254+config JFFS2_SUMMARY
1255+ bool "JFFS2 summary support (EXPERIMENTAL)"
1256+ depends on JFFS2_FS && EXPERIMENTAL
1257+ default n
1258+ help
1259+ This feature makes it possible to use summary information
1260+ for faster filesystem mount.
1261+
1262+ The summary information can be inserted into a filesystem image
1263+ by the utility 'sumtool'.
1264+
1265+ If unsure, say 'N'.
1266+
1267+config JFFS2_FS_XATTR
1268+ bool "JFFS2 XATTR support (EXPERIMENTAL)"
1269+ depends on JFFS2_FS && EXPERIMENTAL
1270+ default n
1271+ help
1272+ Extended attributes are name:value pairs associated with inodes by
1273+ the kernel or by users (see the attr(5) manual page, or visit
1274+ <http://acl.bestbits.at/> for details).
1275+
1276+ If unsure, say N.
1277+
1278+config JFFS2_FS_POSIX_ACL
1279+ bool "JFFS2 POSIX Access Control Lists"
1280+ depends on JFFS2_FS_XATTR
1281+ default y
1282+ select FS_POSIX_ACL
1283+ help
1284+ Posix Access Control Lists (ACLs) support permissions for users and
1285+ groups beyond the owner/group/world scheme.
1286+
1287+ To learn more about Access Control Lists, visit the Posix ACLs for
1288+ Linux website <http://acl.bestbits.at/>.
1289+
1290+ If you don't know what Access Control Lists are, say N
1291+
1292+config JFFS2_FS_SECURITY
1293+ bool "JFFS2 Security Labels"
1294+ depends on JFFS2_FS_XATTR
1295+ default y
1296+ help
1297+ Security labels support alternative access control models
1298+ implemented by security modules like SELinux. This option
1299+ enables an extended attribute handler for file security
1300+ labels in the jffs2 filesystem.
1301+
1302+ If you are not using a security module that requires using
1303+ extended attributes for file security labels, say N.
1304+
1305+config JFFS2_COMPRESSION_OPTIONS
1306+ bool "Advanced compression options for JFFS2"
1307+ depends on JFFS2_FS
1308+ default n
1309+ help
1310+ Enabling this option allows you to explicitly choose which
1311+ compression modules, if any, are enabled in JFFS2. Removing
1312+ compressors can mean you cannot read existing file systems,
1313+ and enabling experimental compressors can mean that you
1314+ write a file system which cannot be read by a standard kernel.
1315+
1316+ If unsure, you should _definitely_ say 'N'.
1317+
1318+config JFFS2_ZLIB
1319+ bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
1320+ select ZLIB_INFLATE
1321+ select ZLIB_DEFLATE
1322+ depends on JFFS2_FS
1323+ default y
1324+ help
1325+ Zlib is designed to be a free, general-purpose, legally unencumbered,
1326+ lossless data-compression library for use on virtually any computer
1327+ hardware and operating system. See <http://www.gzip.org/zlib/> for
1328+ further information.
1329+
1330+ Say 'Y' if unsure.
1331+
1332+config JFFS2_LZO
1333+ bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
1334+ select LZO_COMPRESS
1335+ select LZO_DECOMPRESS
1336+ depends on JFFS2_FS
1337+ default n
1338+ help
1339+ minilzo-based compression. Generally works better than Zlib.
1340+
1341+ This feature was added in July, 2007. Say 'N' if you need
1342+ compatibility with older bootloaders or kernels.
1343+
1344+config JFFS2_RTIME
1345+ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
1346+ depends on JFFS2_FS
1347+ default y
1348+ help
1349+ Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
1350+
1351+config JFFS2_RUBIN
1352+ bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
1353+ depends on JFFS2_FS
1354+ default n
1355+ help
1356+ RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
1357+
1358+choice
1359+ prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
1360+ default JFFS2_CMODE_PRIORITY
1361+ depends on JFFS2_FS
1362+ help
1363+ You can set here the default compression mode of JFFS2 from
1364+ the available compression modes. Don't touch if unsure.
1365+
1366+config JFFS2_CMODE_NONE
1367+ bool "no compression"
1368+ help
1369+ Uses no compression.
1370+
1371+config JFFS2_CMODE_PRIORITY
1372+ bool "priority"
1373+ help
1374+ Tries the compressors in a predefined order and chooses the first
1375+ successful one.
1376+
1377+config JFFS2_CMODE_SIZE
1378+ bool "size (EXPERIMENTAL)"
1379+ help
1380+ Tries all compressors and chooses the one which has the smallest
1381+ result.
1382+
1383+config JFFS2_CMODE_FAVOURLZO
1384+ bool "Favour LZO"
1385+ help
1386+ Tries all compressors and chooses the one which has the smallest
1387+ result but gives some preference to LZO (which has faster
1388+ decompression) at the expense of size.
1389+
1390+endchoice
1391+
1392+# UBIFS File system configuration
1393+source "fs/ubifs/Kconfig"
1394+
1395+config CRAMFS
1396+ tristate "Compressed ROM file system support (cramfs)"
1397+ depends on BLOCK
1398+ select ZLIB_INFLATE
1399+ help
1400+ Saying Y here includes support for CramFs (Compressed ROM File
1401+ System). CramFs is designed to be a simple, small, and compressed
1402+ file system for ROM based embedded systems. CramFs is read-only,
1403+ limited to 256MB file systems (with 16MB files), and doesn't support
1404+ 16/32 bits uid/gid, hard links and timestamps.
1405+
1406+ See <file:Documentation/filesystems/cramfs.txt> and
1407+ <file:fs/cramfs/README> for further information.
1408+
1409+ To compile this as a module, choose M here: the module will be called
1410+ cramfs. Note that the root file system (the one containing the
1411+ directory /) cannot be compiled as a module.
1412+
1413+ If unsure, say N.
1414+
1415+config VXFS_FS
1416+ tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
1417+ depends on BLOCK
1418+ help
1419+ FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
1420+ file system format. VERITAS VxFS(TM) is the standard file system
1421+ of SCO UnixWare (and possibly others) and optionally available
1422+ for Sunsoft Solaris, HP-UX and many other operating systems.
1423+ Currently only readonly access is supported.
1424+
1425+ NOTE: the file system type as used by mount(1), mount(2) and
1426+ fstab(5) is 'vxfs' as it describes the file system format, not
1427+ the actual driver.
1428+
1429+ To compile this as a module, choose M here: the module will be
1430+ called freevxfs. If unsure, say N.
1431+
1432+config MINIX_FS
1433+ tristate "Minix file system support"
1434+ depends on BLOCK
1435+ help
1436+ Minix is a simple operating system used in many classes about OS's.
1437+ The minix file system (method to organize files on a hard disk
1438+ partition or a floppy disk) was the original file system for Linux,
1439+ but has been superseded by the second extended file system ext2fs.
1440+ You don't want to use the minix file system on your hard disk
1441+ because of certain built-in restrictions, but it is sometimes found
1442+ on older Linux floppy disks. This option will enlarge your kernel
1443+ by about 28 KB. If unsure, say N.
1444+
1445+ To compile this file system support as a module, choose M here: the
1446+ module will be called minix. Note that the file system of your root
1447+ partition (the one containing the directory /) cannot be compiled as
1448+ a module.
1449+
1450+config OMFS_FS
1451+ tristate "SonicBlue Optimized MPEG File System support"
1452+ depends on BLOCK
1453+ select CRC_ITU_T
1454+ help
1455+ This is the proprietary file system used by the Rio Karma music
1456+ player and ReplayTV DVR. Despite the name, this filesystem is not
1457+ more efficient than a standard FS for MPEG files, in fact likely
1458+ the opposite is true. Say Y if you have either of these devices
1459+ and wish to mount its disk.
1460+
1461+ To compile this file system support as a module, choose M here: the
1462+ module will be called omfs. If unsure, say N.
1463+
1464+config HPFS_FS
1465+ tristate "OS/2 HPFS file system support"
1466+ depends on BLOCK
1467+ help
1468+ OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
1469+ is the file system used for organizing files on OS/2 hard disk
1470+ partitions. Say Y if you want to be able to read files from and
1471+ write files to an OS/2 HPFS partition on your hard drive. OS/2
1472+ floppies however are in regular MSDOS format, so you don't need this
1473+ option in order to be able to read them. Read
1474+ <file:Documentation/filesystems/hpfs.txt>.
1475+
1476+ To compile this file system support as a module, choose M here: the
1477+ module will be called hpfs. If unsure, say N.
1478+
1479+
1480+config QNX4FS_FS
1481+ tristate "QNX4 file system support (read only)"
1482+ depends on BLOCK
1483+ help
1484+ This is the file system used by the real-time operating systems
1485+ QNX 4 and QNX 6 (the latter is also called QNX RTP).
1486+ Further information is available at <http://www.qnx.com/>.
1487+ Say Y if you intend to mount QNX hard disks or floppies.
1488+ Unless you say Y to "QNX4FS read-write support" below, you will
1489+ only be able to read these file systems.
1490+
1491+ To compile this file system support as a module, choose M here: the
1492+ module will be called qnx4.
1493+
1494+ If you don't know whether you need it, then you don't need it:
1495+ answer N.
1496+
1497+config QNX4FS_RW
1498+ bool "QNX4FS write support (DANGEROUS)"
1499+ depends on QNX4FS_FS && EXPERIMENTAL && BROKEN
1500+ help
1501+ Say Y if you want to test write support for QNX4 file systems.
1502+
1503+ It's currently broken, so for now:
1504+ answer N.
1505+
1506+config ROMFS_FS
1507+ tristate "ROM file system support"
1508+ depends on BLOCK
1509+ ---help---
1510+ This is a very small read-only file system mainly intended for
1511+ initial ram disks of installation disks, but it could be used for
1512+ other read-only media as well. Read
1513+ <file:Documentation/filesystems/romfs.txt> for details.
1514+
1515+ To compile this file system support as a module, choose M here: the
1516+ module will be called romfs. Note that the file system of your
1517+ root partition (the one containing the directory /) cannot be a
1518+ module.
1519+
1520+ If you don't know whether you need it, then you don't need it:
1521+ answer N.
1522+
1523+
1524+config SYSV_FS
1525+ tristate "System V/Xenix/V7/Coherent file system support"
1526+ depends on BLOCK
1527+ help
1528+ SCO, Xenix and Coherent are commercial Unix systems for Intel
1529+ machines, and Version 7 was used on the DEC PDP-11. Saying Y
1530+ here would allow you to read from their floppies and hard disk
1531+ partitions.
1532+
1533+ If you have floppies or hard disk partitions like that, it is likely
1534+ that they contain binaries from those other Unix systems; in order
1535+ to run these binaries, you will want to install linux-abi which is
1536+ a set of kernel modules that lets you run SCO, Xenix, Wyse,
1537+ UnixWare, Dell Unix and System V programs under Linux. It is
1538+ available via FTP (user: ftp) from
1539+ <ftp://ftp.openlinux.org/pub/people/hch/linux-abi/>).
1540+ NOTE: that will work only for binaries from Intel-based systems;
1541+ PDP ones will have to wait until somebody ports Linux to -11 ;-)
1542+
1543+ If you only intend to mount files from some other Unix over the
1544+ network using NFS, you don't need the System V file system support
1545+ (but you need NFS file system support obviously).
1546+
1547+ Note that this option is generally not needed for floppies, since a
1548+ good portable way to transport files and directories between unixes
1549+ (and even other operating systems) is given by the tar program ("man
1550+ tar" or preferably "info tar"). Note also that this option has
1551+ nothing whatsoever to do with the option "System V IPC". Read about
1552+ the System V file system in
1553+ <file:Documentation/filesystems/sysv-fs.txt>.
1554+ Saying Y here will enlarge your kernel by about 27 KB.
1555+
1556+ To compile this as a module, choose M here: the module will be called
1557+ sysv.
1558+
1559+ If you haven't heard about all of this before, it's safe to say N.
1560+
1561+
1562+config UFS_FS
1563+ tristate "UFS file system support (read only)"
1564+ depends on BLOCK
1565+ help
1566+ BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
1567+ OpenBSD and NeXTstep) use a file system called UFS. Some System V
1568+ Unixes can create and mount hard disk partitions and diskettes using
1569+ this file system as well. Saying Y here will allow you to read from
1570+ these partitions; if you also want to write to them, say Y to the
1571+ experimental "UFS file system write support", below. Please read the
1572+ file <file:Documentation/filesystems/ufs.txt> for more information.
1573+
1574+ The recently released UFS2 variant (used in FreeBSD 5.x) is
1575+ READ-ONLY supported.
1576+
1577+ Note that this option is generally not needed for floppies, since a
1578+ good portable way to transport files and directories between unixes
1579+ (and even other operating systems) is given by the tar program ("man
1580+ tar" or preferably "info tar").
1581+
1582+ When accessing NeXTstep files, you may need to convert them from the
1583+ NeXT character set to the Latin1 character set; use the program
1584+ recode ("info recode") for this purpose.
1585+
1586+ To compile the UFS file system support as a module, choose M here: the
1587+ module will be called ufs.
1588+
1589+ If you haven't heard about all of this before, it's safe to say N.
1590+
1591+config UFS_FS_WRITE
1592+ bool "UFS file system write support (DANGEROUS)"
1593+ depends on UFS_FS && EXPERIMENTAL
1594+ help
1595+ Say Y here if you want to try writing to UFS partitions. This is
1596+ experimental, so you should back up your UFS partitions beforehand.
1597+
1598+config UFS_DEBUG
1599+ bool "UFS debugging"
1600+ depends on UFS_FS
1601+ help
1602+ If you are experiencing any problems with the UFS filesystem, say
1603+ Y here. This will result in _many_ additional debugging messages to be
1604+ written to the system log.
1605+
1606+endmenu
1607+
1608+menuconfig NETWORK_FILESYSTEMS
1609+ bool "Network File Systems"
1610+ default y
1611+ depends on NET
1612+ ---help---
1613+ Say Y here to get to see options for network filesystems and
1614+ filesystem-related networking code, such as NFS daemon and
1615+ RPCSEC security modules.
1616+
1617+ This option alone does not add any kernel code.
1618+
1619+ If you say N, all options in this submenu will be skipped and
1620+ disabled; if unsure, say Y here.
1621+
1622+if NETWORK_FILESYSTEMS
1623+
1624+config NFS_FS
1625+ tristate "NFS client support"
1626+ depends on INET
1627+ select LOCKD
1628+ select SUNRPC
1629+ select NFS_ACL_SUPPORT if NFS_V3_ACL
1630+ help
1631+ Choose Y here if you want to access files residing on other
1632+ computers using Sun's Network File System protocol. To compile
1633+ this file system support as a module, choose M here: the module
1634+ will be called nfs.
1635+
1636+ To mount file systems exported by NFS servers, you also need to
1637+ install the user space mount.nfs command which can be found in
1638+ the Linux nfs-utils package, available from http://linux-nfs.org/.
1639+ Information about using the mount command is available in the
1640+ mount(8) man page. More detail about the Linux NFS client
1641+ implementation is available via the nfs(5) man page.
1642+
1643+ Below you can choose which versions of the NFS protocol are
1644+ available in the kernel to mount NFS servers. Support for NFS
1645+ version 2 (RFC 1094) is always available when NFS_FS is selected.
1646+
1647+ To configure a system which mounts its root file system via NFS
1648+ at boot time, say Y here, select "Kernel level IP
1649+ autoconfiguration" in the NETWORK menu, and select "Root file
1650+ system on NFS" below. You cannot compile this file system as a
1651+ module in this case.
1652+
1653+ If unsure, say N.
1654+
1655+config NFS_V3
1656+ bool "NFS client support for NFS version 3"
1657+ depends on NFS_FS
1658+ help
1659+ This option enables support for version 3 of the NFS protocol
1660+ (RFC 1813) in the kernel's NFS client.
1661+
1662+ If unsure, say Y.
1663+
1664+config NFS_V3_ACL
1665+ bool "NFS client support for the NFSv3 ACL protocol extension"
1666+ depends on NFS_V3
1667+ help
1668+ Some NFS servers support an auxiliary NFSv3 ACL protocol that
1669+ Sun added to Solaris but never became an official part of the
1670+ NFS version 3 protocol. This protocol extension allows
1671+ applications on NFS clients to manipulate POSIX Access Control
1672+ Lists on files residing on NFS servers. NFS servers enforce
1673+ ACLs on local files whether this protocol is available or not.
1674+
1675+ Choose Y here if your NFS server supports the Solaris NFSv3 ACL
1676+ protocol extension and you want your NFS client to allow
1677+ applications to access and modify ACLs on files on the server.
1678+
1679+ Most NFS servers don't support the Solaris NFSv3 ACL protocol
1680+ extension. You can choose N here or specify the "noacl" mount
1681+ option to prevent your NFS client from trying to use the NFSv3
1682+ ACL protocol.
1683+
1684+ If unsure, say N.
1685+
1686+config NFS_V4
1687+ bool "NFS client support for NFS version 4 (EXPERIMENTAL)"
1688+ depends on NFS_FS && EXPERIMENTAL
1689+ select RPCSEC_GSS_KRB5
1690+ help
1691+ This option enables support for version 4 of the NFS protocol
1692+ (RFC 3530) in the kernel's NFS client.
1693+
1694+ To mount NFS servers using NFSv4, you also need to install user
1695+ space programs which can be found in the Linux nfs-utils package,
1696+ available from http://linux-nfs.org/.
1697+
1698+ If unsure, say N.
1699+
1700+config ROOT_NFS
1701+ bool "Root file system on NFS"
1702+ depends on NFS_FS=y && IP_PNP
1703+ help
1704+ If you want your system to mount its root file system via NFS,
1705+ choose Y here. This is common practice for managing systems
1706+ without local permanent storage. For details, read
1707+ <file:Documentation/filesystems/nfsroot.txt>.
1708+
1709+ Most people say N here.
1710+
1711+config NFSD
1712+ tristate "NFS server support"
1713+ depends on INET
1714+ select LOCKD
1715+ select SUNRPC
1716+ select EXPORTFS
1717+ select NFS_ACL_SUPPORT if NFSD_V2_ACL
1718+ help
1719+ Choose Y here if you want to allow other computers to access
1720+ files residing on this system using Sun's Network File System
1721+ protocol. To compile the NFS server support as a module,
1722+ choose M here: the module will be called nfsd.
1723+
1724+ You may choose to use a user-space NFS server instead, in which
1725+ case you can choose N here.
1726+
1727+ To export local file systems using NFS, you also need to install
1728+ user space programs which can be found in the Linux nfs-utils
1729+ package, available from http://linux-nfs.org/. More detail about
1730+ the Linux NFS server implementation is available via the
1731+ exports(5) man page.
1732+
1733+ Below you can choose which versions of the NFS protocol are
1734+ available to clients mounting the NFS server on this system.
1735+ Support for NFS version 2 (RFC 1094) is always available when
1736+ CONFIG_NFSD is selected.
1737+
1738+ If unsure, say N.
1739+
1740+config NFSD_V2_ACL
1741+ bool
1742+ depends on NFSD
1743+
1744+config NFSD_V3
1745+ bool "NFS server support for NFS version 3"
1746+ depends on NFSD
1747+ help
1748+ This option enables support in your system's NFS server for
1749+ version 3 of the NFS protocol (RFC 1813).
1750+
1751+ If unsure, say Y.
1752+
1753+config NFSD_V3_ACL
1754+ bool "NFS server support for the NFSv3 ACL protocol extension"
1755+ depends on NFSD_V3
1756+ select NFSD_V2_ACL
1757+ help
1758+ Solaris NFS servers support an auxiliary NFSv3 ACL protocol that
1759+ never became an official part of the NFS version 3 protocol.
1760+ This protocol extension allows applications on NFS clients to
1761+ manipulate POSIX Access Control Lists on files residing on NFS
1762+ servers. NFS servers enforce POSIX ACLs on local files whether
1763+ this protocol is available or not.
1764+
1765+ This option enables support in your system's NFS server for the
1766+ NFSv3 ACL protocol extension allowing NFS clients to manipulate
1767+ POSIX ACLs on files exported by your system's NFS server. NFS
1768+ clients which support the Solaris NFSv3 ACL protocol can then
1769+ access and modify ACLs on your NFS server.
1770+
1771+ To store ACLs on your NFS server, you also need to enable ACL-
1772+ related CONFIG options for your local file systems of choice.
1773+
1774+ If unsure, say N.
1775+
1776+config NFSD_V4
1777+ bool "NFS server support for NFS version 4 (EXPERIMENTAL)"
1778+ depends on NFSD && PROC_FS && EXPERIMENTAL
1779+ select NFSD_V3
1780+ select FS_POSIX_ACL
1781+ select RPCSEC_GSS_KRB5
1782+ help
1783+ This option enables support in your system's NFS server for
1784+ version 4 of the NFS protocol (RFC 3530).
1785+
1786+ To export files using NFSv4, you need to install additional user
1787+ space programs which can be found in the Linux nfs-utils package,
1788+ available from http://linux-nfs.org/.
1789+
1790+ If unsure, say N.
1791+
1792+config LOCKD
1793+ tristate
1794+
1795+config LOCKD_V4
1796+ bool
1797+ depends on NFSD_V3 || NFS_V3
1798+ default y
1799+
1800+config EXPORTFS
1801+ tristate
1802+
1803+config NFS_ACL_SUPPORT
1804+ tristate
1805+ select FS_POSIX_ACL
1806+
1807+config NFS_COMMON
1808+ bool
1809+ depends on NFSD || NFS_FS
1810+ default y
1811+
1812+config SUNRPC
1813+ tristate
1814+
1815+config SUNRPC_GSS
1816+ tristate
1817+
1818+config SUNRPC_XPRT_RDMA
1819+ tristate
1820+ depends on SUNRPC && INFINIBAND && EXPERIMENTAL
1821+ default SUNRPC && INFINIBAND
1822+ help
1823+ This option enables an RPC client transport capability that
1824+ allows the NFS client to mount servers via an RDMA-enabled
1825+ transport.
1826+
1827+ To compile RPC client RDMA transport support as a module,
1828+ choose M here: the module will be called xprtrdma.
1829+
1830+ If unsure, say N.
1831+
1832+config RPCSEC_GSS_KRB5
1833+ tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
1834+ depends on SUNRPC && EXPERIMENTAL
1835+ select SUNRPC_GSS
1836+ select CRYPTO
1837+ select CRYPTO_MD5
1838+ select CRYPTO_DES
1839+ select CRYPTO_CBC
1840+ help
1841+ Choose Y here to enable Secure RPC using the Kerberos version 5
1842+ GSS-API mechanism (RFC 1964).
1843+
1844+ Secure RPC calls with Kerberos require an auxiliary user-space
1845+ daemon which may be found in the Linux nfs-utils package
1846+ available from http://linux-nfs.org/. In addition, user-space
1847+ Kerberos support should be installed.
1848+
1849+ If unsure, say N.
1850+
1851+config RPCSEC_GSS_SPKM3
1852+ tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
1853+ depends on SUNRPC && EXPERIMENTAL
1854+ select SUNRPC_GSS
1855+ select CRYPTO
1856+ select CRYPTO_MD5
1857+ select CRYPTO_DES
1858+ select CRYPTO_CAST5
1859+ select CRYPTO_CBC
1860+ help
1861+ Choose Y here to enable Secure RPC using the SPKM3 public key
1862+ GSS-API mechansim (RFC 2025).
1863+
1864+ Secure RPC calls with SPKM3 require an auxiliary userspace
1865+ daemon which may be found in the Linux nfs-utils package
1866+ available from http://linux-nfs.org/.
1867+
1868+ If unsure, say N.
1869+
1870+config SMB_FS
1871+ tristate "SMB file system support (OBSOLETE, please use CIFS)"
1872+ depends on INET
1873+ select NLS
1874+ help
1875+ SMB (Server Message Block) is the protocol Windows for Workgroups
1876+ (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share
1877+ files and printers over local networks. Saying Y here allows you to
1878+ mount their file systems (often called "shares" in this context) and
1879+ access them just like any other Unix directory. Currently, this
1880+ works only if the Windows machines use TCP/IP as the underlying
1881+ transport protocol, and not NetBEUI. For details, read
1882+ <file:Documentation/filesystems/smbfs.txt> and the SMB-HOWTO,
1883+ available from <http://www.tldp.org/docs.html#howto>.
1884+
1885+ Note: if you just want your box to act as an SMB *server* and make
1886+ files and printing services available to Windows clients (which need
1887+ to have a TCP/IP stack), you don't need to say Y here; you can use
1888+ the program SAMBA (available from <ftp://ftp.samba.org/pub/samba/>)
1889+ for that.
1890+
1891+ General information about how to connect Linux, Windows machines and
1892+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
1893+
1894+ To compile the SMB support as a module, choose M here:
1895+ the module will be called smbfs. Most people say N, however.
1896+
1897+config SMB_NLS_DEFAULT
1898+ bool "Use a default NLS"
1899+ depends on SMB_FS
1900+ help
1901+ Enabling this will make smbfs use nls translations by default. You
1902+ need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls
1903+ settings and you need to give the default nls for the SMB server as
1904+ CONFIG_SMB_NLS_REMOTE.
1905+
1906+ The nls settings can be changed at mount time, if your smbmount
1907+ supports that, using the codepage and iocharset parameters.
1908+
1909+ smbmount from samba 2.2.0 or later supports this.
1910+
1911+config SMB_NLS_REMOTE
1912+ string "Default Remote NLS Option"
1913+ depends on SMB_NLS_DEFAULT
1914+ default "cp437"
1915+ help
1916+ This setting allows you to specify a default value for which
1917+ codepage the server uses. If this field is left blank no
1918+ translations will be done by default. The local codepage/charset
1919+ default to CONFIG_NLS_DEFAULT.
1920+
1921+ The nls settings can be changed at mount time, if your smbmount
1922+ supports that, using the codepage and iocharset parameters.
1923+
1924+ smbmount from samba 2.2.0 or later supports this.
1925+
1926+config CIFS
1927+ tristate "CIFS support (advanced network filesystem, SMBFS successor)"
1928+ depends on INET
1929+ select NLS
1930+ help
1931+ This is the client VFS module for the Common Internet File System
1932+ (CIFS) protocol which is the successor to the Server Message Block
1933+ (SMB) protocol, the native file sharing mechanism for most early
1934+ PC operating systems. The CIFS protocol is fully supported by
1935+ file servers such as Windows 2000 (including Windows 2003, NT 4
1936+ and Windows XP) as well by Samba (which provides excellent CIFS
1937+ server support for Linux and many other operating systems). Limited
1938+ support for OS/2 and Windows ME and similar servers is provided as
1939+ well.
1940+
1941+ The cifs module provides an advanced network file system
1942+ client for mounting to CIFS compliant servers. It includes
1943+ support for DFS (hierarchical name space), secure per-user
1944+ session establishment via Kerberos or NTLM or NTLMv2,
1945+ safe distributed caching (oplock), optional packet
1946+ signing, Unicode and other internationalization improvements.
1947+ If you need to mount to Samba or Windows from this machine, say Y.
1948+
1949+config CIFS_STATS
1950+ bool "CIFS statistics"
1951+ depends on CIFS
1952+ help
1953+ Enabling this option will cause statistics for each server share
1954+ mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
1955+
1956+config CIFS_STATS2
1957+ bool "Extended statistics"
1958+ depends on CIFS_STATS
1959+ help
1960+ Enabling this option will allow more detailed statistics on SMB
1961+ request timing to be displayed in /proc/fs/cifs/DebugData and also
1962+ allow optional logging of slow responses to dmesg (depending on the
1963+ value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
1964+ These additional statistics may have a minor effect on performance
1965+ and memory utilization.
1966+
1967+ Unless you are a developer or are doing network performance analysis
1968+ or tuning, say N.
1969+
1970+config CIFS_WEAK_PW_HASH
1971+ bool "Support legacy servers which use weaker LANMAN security"
1972+ depends on CIFS
1973+ help
1974+ Modern CIFS servers including Samba and most Windows versions
1975+ (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
1976+ security mechanisms. These hash the password more securely
1977+ than the mechanisms used in the older LANMAN version of the
1978+ SMB protocol but LANMAN based authentication is needed to
1979+ establish sessions with some old SMB servers.
1980+
1981+ Enabling this option allows the cifs module to mount to older
1982+ LANMAN based servers such as OS/2 and Windows 95, but such
1983+ mounts may be less secure than mounts using NTLM or more recent
1984+ security mechanisms if you are on a public network. Unless you
1985+ have a need to access old SMB servers (and are on a private
1986+ network) you probably want to say N. Even if this support
1987+ is enabled in the kernel build, LANMAN authentication will not be
1988+ used automatically. At runtime LANMAN mounts are disabled but
1989+ can be set to required (or optional) either in
1990+ /proc/fs/cifs (see fs/cifs/README for more detail) or via an
1991+ option on the mount command. This support is disabled by
1992+ default in order to reduce the possibility of a downgrade
1993+ attack.
1994+
1995+ If unsure, say N.
1996+
1997+config CIFS_XATTR
1998+ bool "CIFS extended attributes"
1999+ depends on CIFS
2000+ help
2001+ Extended attributes are name:value pairs associated with inodes by
2002+ the kernel or by users (see the attr(5) manual page, or visit
2003+ <http://acl.bestbits.at/> for details). CIFS maps the name of
2004+ extended attributes beginning with the user namespace prefix
2005+ to SMB/CIFS EAs. EAs are stored on Windows servers without the
2006+ user namespace prefix, but their names are seen by Linux cifs clients
2007+ prefaced by the user namespace prefix. The system namespace
2008+ (used by some filesystems to store ACLs) is not supported at
2009+ this time.
2010+
2011+ If unsure, say N.
2012+
2013+config CIFS_POSIX
2014+ bool "CIFS POSIX Extensions"
2015+ depends on CIFS_XATTR
2016+ help
2017+ Enabling this option will cause the cifs client to attempt to
2018+ negotiate a newer dialect with servers, such as Samba 3.0.5
2019+ or later, that optionally can handle more POSIX like (rather
2020+ than Windows like) file behavior. It also enables
2021+ support for POSIX ACLs (getfacl and setfacl) to servers
2022+ (such as Samba 3.10 and later) which can negotiate
2023+ CIFS POSIX ACL support. If unsure, say N.
2024+
2025+config CIFS_DEBUG2
2026+ bool "Enable additional CIFS debugging routines"
2027+ depends on CIFS
2028+ help
2029+ Enabling this option adds a few more debugging routines
2030+ to the cifs code which slightly increases the size of
2031+ the cifs module and can cause additional logging of debug
2032+ messages in some error paths, slowing performance. This
2033+ option can be turned off unless you are debugging
2034+ cifs problems. If unsure, say N.
2035+
2036+config CIFS_EXPERIMENTAL
2037+ bool "CIFS Experimental Features (EXPERIMENTAL)"
2038+ depends on CIFS && EXPERIMENTAL
2039+ help
2040+ Enables cifs features under testing. These features are
2041+ experimental and currently include DFS support and directory
2042+ change notification ie fcntl(F_DNOTIFY), as well as the upcall
2043+ mechanism which will be used for Kerberos session negotiation
2044+ and uid remapping. Some of these features also may depend on
2045+ setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental
2046+ (which is disabled by default). See the file fs/cifs/README
2047+ for more details. If unsure, say N.
2048+
2049+config CIFS_UPCALL
2050+ bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
2051+ depends on CIFS_EXPERIMENTAL
2052+ depends on KEYS
2053+ help
2054+ Enables an upcall mechanism for CIFS which accesses
2055+ userspace helper utilities to provide SPNEGO packaged (RFC 4178)
2056+ Kerberos tickets which are needed to mount to certain secure servers
2057+ (for which more secure Kerberos authentication is required). If
2058+ unsure, say N.
2059+
2060+config CIFS_DFS_UPCALL
2061+ bool "DFS feature support (EXPERIMENTAL)"
2062+ depends on CIFS_EXPERIMENTAL
2063+ depends on KEYS
2064+ help
2065+ Enables an upcall mechanism for CIFS which contacts userspace
2066+ helper utilities to provide server name resolution (host names to
2067+ IP addresses) which is needed for implicit mounts of DFS junction
2068+ points. If unsure, say N.
2069+
2070+config NCP_FS
2071+ tristate "NCP file system support (to mount NetWare volumes)"
2072+ depends on IPX!=n || INET
2073+ help
2074+ NCP (NetWare Core Protocol) is a protocol that runs over IPX and is
2075+ used by Novell NetWare clients to talk to file servers. It is to
2076+ IPX what NFS is to TCP/IP, if that helps. Saying Y here allows you
2077+ to mount NetWare file server volumes and to access them just like
2078+ any other Unix directory. For details, please read the file
2079+ <file:Documentation/filesystems/ncpfs.txt> in the kernel source and
2080+ the IPX-HOWTO from <http://www.tldp.org/docs.html#howto>.
2081+
2082+ You do not have to say Y here if you want your Linux box to act as a
2083+ file *server* for Novell NetWare clients.
2084+
2085+ General information about how to connect Linux, Windows machines and
2086+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
2087+
2088+ To compile this as a module, choose M here: the module will be called
2089+ ncpfs. Say N unless you are connected to a Novell network.
2090+
2091+source "fs/ncpfs/Kconfig"
2092+
2093+config CODA_FS
2094+ tristate "Coda file system support (advanced network fs)"
2095+ depends on INET
2096+ help
2097+ Coda is an advanced network file system, similar to NFS in that it
2098+ enables you to mount file systems of a remote server and access them
2099+ with regular Unix commands as if they were sitting on your hard
2100+ disk. Coda has several advantages over NFS: support for
2101+ disconnected operation (e.g. for laptops), read/write server
2102+ replication, security model for authentication and encryption,
2103+ persistent client caches and write back caching.
2104+
2105+ If you say Y here, your Linux box will be able to act as a Coda
2106+ *client*. You will need user level code as well, both for the
2107+ client and server. Servers are currently user level, i.e. they need
2108+ no kernel support. Please read
2109+ <file:Documentation/filesystems/coda.txt> and check out the Coda
2110+ home page <http://www.coda.cs.cmu.edu/>.
2111+
2112+ To compile the coda client support as a module, choose M here: the
2113+ module will be called coda.
2114+
2115+config AFS_FS
2116+ tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
2117+ depends on INET && EXPERIMENTAL
2118+ select AF_RXRPC
2119+ help
2120+ If you say Y here, you will get an experimental Andrew File System
2121+ driver. It currently only supports unsecured read-only AFS access.
2122+
2123+ See <file:Documentation/filesystems/afs.txt> for more information.
2124+
2125+ If unsure, say N.
2126+
2127+config AFS_DEBUG
2128+ bool "AFS dynamic debugging"
2129+ depends on AFS_FS
2130+ help
2131+ Say Y here to make runtime controllable debugging messages appear.
2132+
2133+ See <file:Documentation/filesystems/afs.txt> for more information.
2134+
2135+ If unsure, say N.
2136+
2137+config 9P_FS
2138+ tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)"
2139+ depends on INET && NET_9P && EXPERIMENTAL
2140+ help
2141+ If you say Y here, you will get experimental support for
2142+ Plan 9 resource sharing via the 9P2000 protocol.
2143+
2144+ See <http://v9fs.sf.net> for more information.
2145+
2146+ If unsure, say N.
2147+
2148+endif # NETWORK_FILESYSTEMS
2149+
2150+if BLOCK
2151+menu "Partition Types"
2152+
2153+source "fs/partitions/Kconfig"
2154+
2155+endmenu
2156+endif
2157+
2158+source "fs/nls/Kconfig"
2159+source "fs/dlm/Kconfig"
2160+
2161+endmenu
2162diff -uNr a/fs/Makefile b/fs/Makefile
2163--- a/fs/Makefile 2008-07-28 19:40:31.000000000 -0700
2164+++ b/fs/Makefile 2008-08-13 16:18:09.000000000 -0700
2165@@ -74,6 +74,7 @@
2166 obj-$(CONFIG_JBD2) += jbd2/
2167 obj-$(CONFIG_EXT2_FS) += ext2/
2168 obj-$(CONFIG_CRAMFS) += cramfs/
2169+obj-$(CONFIG_SQUASHFS) += squashfs/
2170 obj-y += ramfs/
2171 obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
2172 obj-$(CONFIG_CODA_FS) += coda/
2173diff -uNr a/fs/squashfs/block.c b/fs/squashfs/block.c
2174--- a/fs/squashfs/block.c 1969-12-31 16:00:00.000000000 -0800
2175+++ b/fs/squashfs/block.c 2008-08-13 16:14:50.000000000 -0700
2176@@ -0,0 +1,314 @@
2177+/*
2178+ * Squashfs - a compressed read only filesystem for Linux
2179+ *
2180+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2181+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2182+ *
2183+ * This program is free software; you can redistribute it and/or
2184+ * modify it under the terms of the GNU General Public License
2185+ * as published by the Free Software Foundation; either version 2,
2186+ * or (at your option) any later version.
2187+ *
2188+ * This program is distributed in the hope that it will be useful,
2189+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2190+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2191+ * GNU General Public License for more details.
2192+ *
2193+ * You should have received a copy of the GNU General Public License
2194+ * along with this program; if not, write to the Free Software
2195+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2196+ *
2197+ * block.c
2198+ */
2199+
2200+#include <linux/squashfs_fs.h>
2201+#include <linux/module.h>
2202+#include <linux/zlib.h>
2203+#include <linux/fs.h>
2204+#include <linux/squashfs_fs_sb.h>
2205+#include <linux/squashfs_fs_i.h>
2206+#include <linux/buffer_head.h>
2207+#include <linux/vfs.h>
2208+#include <linux/vmalloc.h>
2209+#include <linux/spinlock.h>
2210+#include <linux/smp_lock.h>
2211+#include <linux/exportfs.h>
2212+
2213+#include "squashfs.h"
2214+static struct buffer_head *get_block_length(struct super_block *s,
2215+ int *cur_index, int *offset, int *c_byte)
2216+{
2217+ struct squashfs_sb_info *msblk = s->s_fs_info;
2218+ unsigned short temp;
2219+ struct buffer_head *bh;
2220+
2221+ if (!(bh = sb_bread(s, *cur_index)))
2222+ goto out;
2223+
2224+ if (msblk->devblksize - *offset == 1) {
2225+ if (msblk->swap)
2226+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2227+ (bh->b_data + *offset));
2228+ else
2229+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2230+ (bh->b_data + *offset));
2231+ brelse(bh);
2232+ if (!(bh = sb_bread(s, ++(*cur_index))))
2233+ goto out;
2234+ if (msblk->swap)
2235+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2236+ bh->b_data);
2237+ else
2238+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2239+ bh->b_data);
2240+ *c_byte = temp;
2241+ *offset = 1;
2242+ } else {
2243+ if (msblk->swap) {
2244+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2245+ (bh->b_data + *offset));
2246+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2247+ (bh->b_data + *offset + 1));
2248+ } else {
2249+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2250+ (bh->b_data + *offset));
2251+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2252+ (bh->b_data + *offset + 1));
2253+ }
2254+ *c_byte = temp;
2255+ *offset += 2;
2256+ }
2257+
2258+ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
2259+ if (*offset == msblk->devblksize) {
2260+ brelse(bh);
2261+ if (!(bh = sb_bread(s, ++(*cur_index))))
2262+ goto out;
2263+ *offset = 0;
2264+ }
2265+ if (*((unsigned char *) (bh->b_data + *offset)) !=
2266+ SQUASHFS_MARKER_BYTE) {
2267+ ERROR("Metadata block marker corrupt @ %x\n",
2268+ *cur_index);
2269+ brelse(bh);
2270+ goto out;
2271+ }
2272+ (*offset)++;
2273+ }
2274+ return bh;
2275+
2276+out:
2277+ return NULL;
2278+}
2279+
2280+
2281+unsigned int squashfs_read_data(struct super_block *s, char *buffer,
2282+ long long index, unsigned int length,
2283+ long long *next_index, int srclength)
2284+{
2285+ struct squashfs_sb_info *msblk = s->s_fs_info;
2286+ struct squashfs_super_block *sblk = &msblk->sblk;
2287+ struct buffer_head **bh;
2288+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
2289+ unsigned int cur_index = index >> msblk->devblksize_log2;
2290+ int bytes, avail_bytes, b = 0, k = 0;
2291+ unsigned int compressed;
2292+ unsigned int c_byte = length;
2293+
2294+ bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) *
2295+ sizeof(struct buffer_head *), GFP_KERNEL);
2296+ if (bh == NULL)
2297+ goto read_failure;
2298+
2299+ if (c_byte) {
2300+ bytes = -offset;
2301+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
2302+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
2303+
2304+ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index,
2305+ compressed ? "" : "un", (unsigned int) c_byte, srclength);
2306+
2307+ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
2308+ goto read_failure;
2309+
2310+ for (b = 0; bytes < (int) c_byte; b++, cur_index++) {
2311+ bh[b] = sb_getblk(s, cur_index);
2312+ if (bh[b] == NULL)
2313+ goto block_release;
2314+ bytes += msblk->devblksize;
2315+ }
2316+ ll_rw_block(READ, b, bh);
2317+ } else {
2318+ if (index < 0 || (index + 2) > sblk->bytes_used)
2319+ goto read_failure;
2320+
2321+ bh[0] = get_block_length(s, &cur_index, &offset, &c_byte);
2322+ if (bh[0] == NULL)
2323+ goto read_failure;
2324+ b = 1;
2325+
2326+ bytes = msblk->devblksize - offset;
2327+ compressed = SQUASHFS_COMPRESSED(c_byte);
2328+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
2329+
2330+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
2331+ ? "" : "un", (unsigned int) c_byte);
2332+
2333+ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
2334+ goto block_release;
2335+
2336+ for (; bytes < c_byte; b++) {
2337+ bh[b] = sb_getblk(s, ++cur_index);
2338+ if (bh[b] == NULL)
2339+ goto block_release;
2340+ bytes += msblk->devblksize;
2341+ }
2342+ ll_rw_block(READ, b - 1, bh + 1);
2343+ }
2344+
2345+ if (compressed) {
2346+ int zlib_err = 0;
2347+
2348+ /*
2349+ * uncompress block
2350+ */
2351+
2352+ mutex_lock(&msblk->read_data_mutex);
2353+
2354+ msblk->stream.next_out = buffer;
2355+ msblk->stream.avail_out = srclength;
2356+
2357+ for (bytes = 0; k < b; k++) {
2358+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
2359+
2360+ wait_on_buffer(bh[k]);
2361+ if (!buffer_uptodate(bh[k]))
2362+ goto release_mutex;
2363+
2364+ msblk->stream.next_in = bh[k]->b_data + offset;
2365+ msblk->stream.avail_in = avail_bytes;
2366+
2367+ if (k == 0) {
2368+ zlib_err = zlib_inflateInit(&msblk->stream);
2369+ if (zlib_err != Z_OK) {
2370+ ERROR("zlib_inflateInit returned unexpected result 0x%x,"
2371+ " srclength %d\n", zlib_err, srclength);
2372+ goto release_mutex;
2373+ }
2374+
2375+ if (avail_bytes == 0) {
2376+ offset = 0;
2377+ brelse(bh[k]);
2378+ continue;
2379+ }
2380+ }
2381+
2382+ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
2383+ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
2384+ ERROR("zlib_inflate returned unexpected result 0x%x,"
2385+ " srclength %d, avail_in %d, avail_out %d\n", zlib_err,
2386+ srclength, msblk->stream.avail_in, msblk->stream.avail_out);
2387+ goto release_mutex;
2388+ }
2389+
2390+ bytes += avail_bytes;
2391+ offset = 0;
2392+ brelse(bh[k]);
2393+ }
2394+
2395+ if (zlib_err != Z_STREAM_END)
2396+ goto release_mutex;
2397+
2398+ zlib_err = zlib_inflateEnd(&msblk->stream);
2399+ if (zlib_err != Z_OK) {
2400+ ERROR("zlib_inflateEnd returned unexpected result 0x%x,"
2401+ " srclength %d\n", zlib_err, srclength);
2402+ goto release_mutex;
2403+ }
2404+ bytes = msblk->stream.total_out;
2405+ mutex_unlock(&msblk->read_data_mutex);
2406+ } else {
2407+ int i;
2408+
2409+ for(i = 0; i < b; i++) {
2410+ wait_on_buffer(bh[i]);
2411+ if (!buffer_uptodate(bh[i]))
2412+ goto block_release;
2413+ }
2414+
2415+ for (bytes = 0; k < b; k++) {
2416+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
2417+
2418+ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
2419+ bytes += avail_bytes;
2420+ offset = 0;
2421+ brelse(bh[k]);
2422+ }
2423+ }
2424+
2425+ if (next_index)
2426+ *next_index = index + c_byte + (length ? 0 :
2427+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2));
2428+
2429+ kfree(bh);
2430+ return bytes;
2431+
2432+release_mutex:
2433+ mutex_unlock(&msblk->read_data_mutex);
2434+
2435+block_release:
2436+ for (; k < b; k++)
2437+ brelse(bh[k]);
2438+
2439+read_failure:
2440+ ERROR("sb_bread failed reading block 0x%x\n", cur_index);
2441+ kfree(bh);
2442+ return 0;
2443+}
2444+
2445+
2446+int squashfs_get_cached_block(struct super_block *s, void *buffer,
2447+ long long block, unsigned int offset,
2448+ int length, long long *next_block,
2449+ unsigned int *next_offset)
2450+{
2451+ struct squashfs_sb_info *msblk = s->s_fs_info;
2452+ int bytes, return_length = length;
2453+ struct squashfs_cache_entry *entry;
2454+
2455+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
2456+
2457+ while (1) {
2458+ entry = squashfs_cache_get(s, msblk->block_cache, block, 0);
2459+ bytes = entry->length - offset;
2460+
2461+ if (entry->error || bytes < 1) {
2462+ return_length = 0;
2463+ goto finish;
2464+ } else if (bytes >= length) {
2465+ if (buffer)
2466+ memcpy(buffer, entry->data + offset, length);
2467+ if (entry->length - offset == length) {
2468+ *next_block = entry->next_index;
2469+ *next_offset = 0;
2470+ } else {
2471+ *next_block = block;
2472+ *next_offset = offset + length;
2473+ }
2474+ goto finish;
2475+ } else {
2476+ if (buffer) {
2477+ memcpy(buffer, entry->data + offset, bytes);
2478+ buffer = (char *) buffer + bytes;
2479+ }
2480+ block = entry->next_index;
2481+ squashfs_cache_put(msblk->block_cache, entry);
2482+ length -= bytes;
2483+ offset = 0;
2484+ }
2485+ }
2486+
2487+finish:
2488+ squashfs_cache_put(msblk->block_cache, entry);
2489+ return return_length;
2490+}
2491diff -uNr a/fs/squashfs/cache.c b/fs/squashfs/cache.c
2492--- a/fs/squashfs/cache.c 1969-12-31 16:00:00.000000000 -0800
2493+++ b/fs/squashfs/cache.c 2008-08-13 16:14:50.000000000 -0700
2494@@ -0,0 +1,189 @@
2495+/*
2496+ * Squashfs - a compressed read only filesystem for Linux
2497+ *
2498+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2499+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2500+ *
2501+ * This program is free software; you can redistribute it and/or
2502+ * modify it under the terms of the GNU General Public License
2503+ * as published by the Free Software Foundation; either version 2,
2504+ * or (at your option) any later version.
2505+ *
2506+ * This program is distributed in the hope that it will be useful,
2507+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2508+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2509+ * GNU General Public License for more details.
2510+ *
2511+ * You should have received a copy of the GNU General Public License
2512+ * along with this program; if not, write to the Free Software
2513+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2514+ *
2515+ * cache.c
2516+ */
2517+
2518+#include <linux/squashfs_fs.h>
2519+#include <linux/module.h>
2520+#include <linux/zlib.h>
2521+#include <linux/fs.h>
2522+#include <linux/squashfs_fs_sb.h>
2523+#include <linux/squashfs_fs_i.h>
2524+#include <linux/buffer_head.h>
2525+#include <linux/vfs.h>
2526+#include <linux/vmalloc.h>
2527+#include <linux/spinlock.h>
2528+#include <linux/smp_lock.h>
2529+#include <linux/exportfs.h>
2530+
2531+#include "squashfs.h"
2532+struct squashfs_cache_entry *squashfs_cache_get(struct super_block *s,
2533+ struct squashfs_cache *cache, long long block, int length)
2534+{
2535+ int i, n;
2536+ struct squashfs_cache_entry *entry;
2537+
2538+ spin_lock(&cache->lock);
2539+
2540+ while (1) {
2541+ for (i = 0; i < cache->entries && cache->entry[i].block != block; i++);
2542+
2543+ if (i == cache->entries) {
2544+ if (cache->unused_blks == 0) {
2545+ cache->waiting ++;
2546+ spin_unlock(&cache->lock);
2547+ wait_event(cache->wait_queue, cache->unused_blks);
2548+ spin_lock(&cache->lock);
2549+ cache->waiting --;
2550+ continue;
2551+ }
2552+
2553+ i = cache->next_blk;
2554+ for (n = 0; n < cache->entries; n++) {
2555+ if (cache->entry[i].locked == 0)
2556+ break;
2557+ i = (i + 1) % cache->entries;
2558+ }
2559+
2560+ cache->next_blk = (i + 1) % cache->entries;
2561+ entry = &cache->entry[i];
2562+
2563+ cache->unused_blks --;
2564+ entry->block = block;
2565+ entry->locked = 1;
2566+ entry->pending = 1;
2567+ entry->waiting = 0;
2568+ entry->error = 0;
2569+ spin_unlock(&cache->lock);
2570+
2571+ entry->length = squashfs_read_data(s, entry->data,
2572+ block, length, &entry->next_index, cache->block_size);
2573+
2574+ spin_lock(&cache->lock);
2575+
2576+ if (entry->length == 0)
2577+ entry->error = 1;
2578+
2579+ entry->pending = 0;
2580+ spin_unlock(&cache->lock);
2581+ if (entry->waiting)
2582+ wake_up_all(&entry->wait_queue);
2583+ goto out;
2584+ }
2585+
2586+ entry = &cache->entry[i];
2587+ if (entry->locked == 0)
2588+ cache->unused_blks --;
2589+ entry->locked++;
2590+
2591+ if (entry->pending) {
2592+ entry->waiting ++;
2593+ spin_unlock(&cache->lock);
2594+ wait_event(entry->wait_queue, !entry->pending);
2595+ goto out;
2596+ }
2597+
2598+ spin_unlock(&cache->lock);
2599+ goto out;
2600+ }
2601+
2602+out:
2603+ TRACE("Got %s %d, start block %lld, locked %d, error %d\n", i,
2604+ cache->name, entry->block, entry->locked, entry->error);
2605+ if (entry->error)
2606+ ERROR("Unable to read %s cache entry [%llx]\n", cache->name, block);
2607+ return entry;
2608+}
2609+
2610+
2611+void squashfs_cache_put(struct squashfs_cache *cache,
2612+ struct squashfs_cache_entry *entry)
2613+{
2614+ spin_lock(&cache->lock);
2615+ entry->locked --;
2616+ if (entry->locked == 0) {
2617+ cache->unused_blks ++;
2618+ spin_unlock(&cache->lock);
2619+ if (cache->waiting)
2620+ wake_up(&cache->wait_queue);
2621+ } else
2622+ spin_unlock(&cache->lock);
2623+}
2624+
2625+
2626+void squashfs_cache_delete(struct squashfs_cache *cache)
2627+{
2628+ int i;
2629+
2630+ if (cache == NULL)
2631+ return;
2632+
2633+ for (i = 0; i < cache->entries; i++)
2634+ if (cache->entry[i].data) {
2635+ if (cache->use_vmalloc)
2636+ vfree(cache->entry[i].data);
2637+ else
2638+ kfree(cache->entry[i].data);
2639+ }
2640+
2641+ kfree(cache);
2642+}
2643+
2644+
2645+struct squashfs_cache *squashfs_cache_init(char *name, int entries,
2646+ int block_size, int use_vmalloc)
2647+{
2648+ int i;
2649+ struct squashfs_cache *cache = kzalloc(sizeof(struct squashfs_cache) +
2650+ entries * sizeof(struct squashfs_cache_entry), GFP_KERNEL);
2651+ if (cache == NULL) {
2652+ ERROR("Failed to allocate %s cache\n", name);
2653+ goto failed;
2654+ }
2655+
2656+ cache->next_blk = 0;
2657+ cache->unused_blks = entries;
2658+ cache->entries = entries;
2659+ cache->block_size = block_size;
2660+ cache->use_vmalloc = use_vmalloc;
2661+ cache->name = name;
2662+ cache->waiting = 0;
2663+ spin_lock_init(&cache->lock);
2664+ init_waitqueue_head(&cache->wait_queue);
2665+
2666+ for (i = 0; i < entries; i++) {
2667+ init_waitqueue_head(&cache->entry[i].wait_queue);
2668+ cache->entry[i].block = SQUASHFS_INVALID_BLK;
2669+ cache->entry[i].data = use_vmalloc ? vmalloc(block_size) :
2670+ kmalloc(block_size, GFP_KERNEL);
2671+ if (cache->entry[i].data == NULL) {
2672+ ERROR("Failed to allocate %s cache entry\n", name);
2673+ goto cleanup;
2674+ }
2675+ }
2676+
2677+ return cache;
2678+
2679+cleanup:
2680+ squashfs_cache_delete(cache);
2681+failed:
2682+ return NULL;
2683+}
2684diff -uNr a/fs/squashfs/dir.c b/fs/squashfs/dir.c
2685--- a/fs/squashfs/dir.c 1969-12-31 16:00:00.000000000 -0800
2686+++ b/fs/squashfs/dir.c 2008-08-13 16:14:50.000000000 -0700
2687@@ -0,0 +1,216 @@
2688+/*
2689+ * Squashfs - a compressed read only filesystem for Linux
2690+ *
2691+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2692+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2693+ *
2694+ * This program is free software; you can redistribute it and/or
2695+ * modify it under the terms of the GNU General Public License
2696+ * as published by the Free Software Foundation; either version 2,
2697+ * or (at your option) any later version.
2698+ *
2699+ * This program is distributed in the hope that it will be useful,
2700+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2701+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2702+ * GNU General Public License for more details.
2703+ *
2704+ * You should have received a copy of the GNU General Public License
2705+ * along with this program; if not, write to the Free Software
2706+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2707+ *
2708+ * dir.c
2709+ */
2710+
2711+#include <linux/squashfs_fs.h>
2712+#include <linux/module.h>
2713+#include <linux/zlib.h>
2714+#include <linux/fs.h>
2715+#include <linux/squashfs_fs_sb.h>
2716+#include <linux/squashfs_fs_i.h>
2717+#include <linux/buffer_head.h>
2718+#include <linux/vfs.h>
2719+#include <linux/vmalloc.h>
2720+#include <linux/spinlock.h>
2721+#include <linux/smp_lock.h>
2722+#include <linux/exportfs.h>
2723+
2724+#include "squashfs.h"
2725+
2726+static const unsigned char squashfs_filetype_table[] = {
2727+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
2728+};
2729+
2730+static int get_dir_index_using_offset(struct super_block *s,
2731+ long long *next_block, unsigned int *next_offset,
2732+ long long index_start, unsigned int index_offset, int i_count,
2733+ long long f_pos)
2734+{
2735+ struct squashfs_sb_info *msblk = s->s_fs_info;
2736+ struct squashfs_super_block *sblk = &msblk->sblk;
2737+ int i, length = 0;
2738+ struct squashfs_dir_index index;
2739+
2740+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
2741+ i_count, (unsigned int) f_pos);
2742+
2743+ f_pos -= 3;
2744+ if (f_pos == 0)
2745+ goto finish;
2746+
2747+ for (i = 0; i < i_count; i++) {
2748+ if (msblk->swap) {
2749+ struct squashfs_dir_index sindex;
2750+ squashfs_get_cached_block(s, &sindex, index_start, index_offset,
2751+ sizeof(sindex), &index_start, &index_offset);
2752+ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
2753+ } else
2754+ squashfs_get_cached_block(s, &index, index_start, index_offset,
2755+ sizeof(index), &index_start, &index_offset);
2756+
2757+ if (index.index > f_pos)
2758+ break;
2759+
2760+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
2761+ index.size + 1, &index_start, &index_offset);
2762+
2763+ length = index.index;
2764+ *next_block = index.start_block + sblk->directory_table_start;
2765+ }
2766+
2767+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
2768+
2769+finish:
2770+ return length + 3;
2771+}
2772+
2773+
2774+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
2775+{
2776+ struct inode *i = file->f_dentry->d_inode;
2777+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
2778+ struct squashfs_super_block *sblk = &msblk->sblk;
2779+ long long next_block = SQUASHFS_I(i)->start_block +
2780+ sblk->directory_table_start;
2781+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count;
2782+ struct squashfs_dir_header dirh;
2783+ struct squashfs_dir_entry *dire;
2784+
2785+ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
2786+
2787+ dire = kmalloc(sizeof(struct squashfs_dir_entry) +
2788+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
2789+ if (dire == NULL) {
2790+ ERROR("Failed to allocate squashfs_dir_entry\n");
2791+ goto finish;
2792+ }
2793+
2794+ while(file->f_pos < 3) {
2795+ char *name;
2796+ int size, i_ino;
2797+
2798+ if(file->f_pos == 0) {
2799+ name = ".";
2800+ size = 1;
2801+ i_ino = i->i_ino;
2802+ } else {
2803+ name = "..";
2804+ size = 2;
2805+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
2806+ }
2807+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
2808+ (unsigned int) dirent, name, size, (int)
2809+ file->f_pos, i_ino, squashfs_filetype_table[1]);
2810+
2811+ if (filldir(dirent, name, size, file->f_pos, i_ino,
2812+ squashfs_filetype_table[1]) < 0) {
2813+ TRACE("Filldir returned less than 0\n");
2814+ goto finish;
2815+ }
2816+ file->f_pos += size;
2817+ }
2818+
2819+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
2820+ SQUASHFS_I(i)->u.s2.directory_index_start,
2821+ SQUASHFS_I(i)->u.s2.directory_index_offset,
2822+ SQUASHFS_I(i)->u.s2.directory_index_count, file->f_pos);
2823+
2824+ while (length < i_size_read(i)) {
2825+ /* read directory header */
2826+ if (msblk->swap) {
2827+ struct squashfs_dir_header sdirh;
2828+
2829+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block,
2830+ next_offset, sizeof(sdirh), &next_block, &next_offset))
2831+ goto failed_read;
2832+
2833+ length += sizeof(sdirh);
2834+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
2835+ } else {
2836+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block,
2837+ next_offset, sizeof(dirh), &next_block, &next_offset))
2838+ goto failed_read;
2839+
2840+ length += sizeof(dirh);
2841+ }
2842+
2843+ dir_count = dirh.count + 1;
2844+ while (dir_count--) {
2845+ if (msblk->swap) {
2846+ struct squashfs_dir_entry sdire;
2847+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block,
2848+ next_offset, sizeof(sdire), &next_block, &next_offset))
2849+ goto failed_read;
2850+
2851+ length += sizeof(sdire);
2852+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
2853+ } else {
2854+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block,
2855+ next_offset, sizeof(*dire), &next_block, &next_offset))
2856+ goto failed_read;
2857+
2858+ length += sizeof(*dire);
2859+ }
2860+
2861+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block,
2862+ next_offset, dire->size + 1, &next_block, &next_offset))
2863+ goto failed_read;
2864+
2865+ length += dire->size + 1;
2866+
2867+ if (file->f_pos >= length)
2868+ continue;
2869+
2870+ dire->name[dire->size + 1] = '\0';
2871+
2872+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
2873+ (unsigned int) dirent, dire->name, dire->size + 1,
2874+ (int) file->f_pos, dirh.start_block, dire->offset,
2875+ dirh.inode_number + dire->inode_number,
2876+ squashfs_filetype_table[dire->type]);
2877+
2878+ if (filldir(dirent, dire->name, dire->size + 1, file->f_pos,
2879+ dirh.inode_number + dire->inode_number,
2880+ squashfs_filetype_table[dire->type]) < 0) {
2881+ TRACE("Filldir returned less than 0\n");
2882+ goto finish;
2883+ }
2884+ file->f_pos = length;
2885+ }
2886+ }
2887+
2888+finish:
2889+ kfree(dire);
2890+ return 0;
2891+
2892+failed_read:
2893+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
2894+ next_offset);
2895+ kfree(dire);
2896+ return 0;
2897+}
2898+
2899+
2900+const struct file_operations squashfs_dir_ops = {
2901+ .read = generic_read_dir,
2902+ .readdir = squashfs_readdir
2903+};
2904diff -uNr a/fs/squashfs/export.c b/fs/squashfs/export.c
2905--- a/fs/squashfs/export.c 1969-12-31 16:00:00.000000000 -0800
2906+++ b/fs/squashfs/export.c 2008-08-13 16:14:50.000000000 -0700
2907@@ -0,0 +1,171 @@
2908+/*
2909+ * Squashfs - a compressed read only filesystem for Linux
2910+ *
2911+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2912+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2913+ *
2914+ * This program is free software; you can redistribute it and/or
2915+ * modify it under the terms of the GNU General Public License
2916+ * as published by the Free Software Foundation; either version 2,
2917+ * or (at your option) any later version.
2918+ *
2919+ * This program is distributed in the hope that it will be useful,
2920+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2921+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2922+ * GNU General Public License for more details.
2923+ *
2924+ * You should have received a copy of the GNU General Public License
2925+ * along with this program; if not, write to the Free Software
2926+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2927+ *
2928+ * export.c
2929+ */
2930+
2931+#include <linux/squashfs_fs.h>
2932+#include <linux/module.h>
2933+#include <linux/zlib.h>
2934+#include <linux/fs.h>
2935+#include <linux/squashfs_fs_sb.h>
2936+#include <linux/squashfs_fs_i.h>
2937+#include <linux/buffer_head.h>
2938+#include <linux/vfs.h>
2939+#include <linux/vmalloc.h>
2940+#include <linux/spinlock.h>
2941+#include <linux/smp_lock.h>
2942+#include <linux/exportfs.h>
2943+
2944+#include "squashfs.h"
2945+static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino)
2946+{
2947+ struct squashfs_sb_info *msblk = s->s_fs_info;
2948+ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)];
2949+ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1);
2950+ squashfs_inode_t inode;
2951+
2952+ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino);
2953+
2954+ if (msblk->swap) {
2955+ squashfs_inode_t sinode;
2956+
2957+ if (!squashfs_get_cached_block(s, &sinode, start, offset,
2958+ sizeof(sinode), &start, &offset))
2959+ goto out;
2960+ SQUASHFS_SWAP_INODE_T((&inode), &sinode);
2961+ } else if (!squashfs_get_cached_block(s, &inode, start, offset,
2962+ sizeof(inode), &start, &offset))
2963+ goto out;
2964+
2965+ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode);
2966+
2967+ return inode;
2968+
2969+out:
2970+ return SQUASHFS_INVALID_BLK;
2971+}
2972+
2973+
2974+static struct dentry *squashfs_export_iget(struct super_block *s,
2975+ unsigned int inode_number)
2976+{
2977+ squashfs_inode_t inode;
2978+ struct inode *i;
2979+ struct dentry *dentry;
2980+
2981+ TRACE("Entered squashfs_export_iget\n");
2982+
2983+ inode = squashfs_inode_lookup(s, inode_number);
2984+ if(inode == SQUASHFS_INVALID_BLK) {
2985+ dentry = ERR_PTR(-ENOENT);
2986+ goto failure;
2987+ }
2988+
2989+ i = squashfs_iget(s, inode, inode_number);
2990+ if(i == NULL) {
2991+ dentry = ERR_PTR(-EACCES);
2992+ goto failure;
2993+ }
2994+
2995+ dentry = d_alloc_anon(i);
2996+ if (dentry == NULL) {
2997+ iput(i);
2998+ dentry = ERR_PTR(-ENOMEM);
2999+ }
3000+
3001+failure:
3002+ return dentry;
3003+}
3004+
3005+
3006+static struct dentry *squashfs_fh_to_dentry(struct super_block *s,
3007+ struct fid *fid, int fh_len, int fh_type)
3008+{
3009+ if((fh_type != FILEID_INO32_GEN && fh_type != FILEID_INO32_GEN_PARENT) ||
3010+ fh_len < 2)
3011+ return NULL;
3012+
3013+ return squashfs_export_iget(s, fid->i32.ino);
3014+}
3015+
3016+
3017+static struct dentry *squashfs_fh_to_parent(struct super_block *s,
3018+ struct fid *fid, int fh_len, int fh_type)
3019+{
3020+ if(fh_type != FILEID_INO32_GEN_PARENT || fh_len < 4)
3021+ return NULL;
3022+
3023+ return squashfs_export_iget(s, fid->i32.parent_ino);
3024+}
3025+
3026+
3027+static struct dentry *squashfs_get_parent(struct dentry *child)
3028+{
3029+ struct inode *i = child->d_inode;
3030+
3031+ TRACE("Entered squashfs_get_parent\n");
3032+
3033+ return squashfs_export_iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
3034+}
3035+
3036+
3037+int read_inode_lookup_table(struct super_block *s)
3038+{
3039+ struct squashfs_sb_info *msblk = s->s_fs_info;
3040+ struct squashfs_super_block *sblk = &msblk->sblk;
3041+ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes);
3042+
3043+ TRACE("In read_inode_lookup_table, length %d\n", length);
3044+
3045+ /* Allocate inode lookup table */
3046+ msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL);
3047+ if (msblk->inode_lookup_table == NULL) {
3048+ ERROR("Failed to allocate inode lookup table\n");
3049+ return 0;
3050+ }
3051+
3052+ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table,
3053+ sblk->lookup_table_start, length |
3054+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3055+ ERROR("unable to read inode lookup table\n");
3056+ return 0;
3057+ }
3058+
3059+ if (msblk->swap) {
3060+ int i;
3061+ long long block;
3062+
3063+ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) {
3064+ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block),
3065+ &msblk->inode_lookup_table[i], 1);
3066+ msblk->inode_lookup_table[i] = block;
3067+ }
3068+ }
3069+
3070+ return 1;
3071+}
3072+
3073+
3074+const struct export_operations squashfs_export_ops = {
3075+ .fh_to_dentry = squashfs_fh_to_dentry,
3076+ .fh_to_parent = squashfs_fh_to_parent,
3077+ .get_parent = squashfs_get_parent
3078+};
3079diff -uNr a/fs/squashfs/file.c b/fs/squashfs/file.c
3080--- a/fs/squashfs/file.c 1969-12-31 16:00:00.000000000 -0800
3081+++ b/fs/squashfs/file.c 2008-08-13 16:14:50.000000000 -0700
3082@@ -0,0 +1,430 @@
3083+/*
3084+ * Squashfs - a compressed read only filesystem for Linux
3085+ *
3086+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3087+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3088+ *
3089+ * This program is free software; you can redistribute it and/or
3090+ * modify it under the terms of the GNU General Public License
3091+ * as published by the Free Software Foundation; either version 2,
3092+ * or (at your option) any later version.
3093+ *
3094+ * This program is distributed in the hope that it will be useful,
3095+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3096+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3097+ * GNU General Public License for more details.
3098+ *
3099+ * You should have received a copy of the GNU General Public License
3100+ * along with this program; if not, write to the Free Software
3101+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3102+ *
3103+ * file.c
3104+ */
3105+
3106+#include <linux/squashfs_fs.h>
3107+#include <linux/module.h>
3108+#include <linux/zlib.h>
3109+#include <linux/fs.h>
3110+#include <linux/squashfs_fs_sb.h>
3111+#include <linux/squashfs_fs_i.h>
3112+#include <linux/buffer_head.h>
3113+#include <linux/vfs.h>
3114+#include <linux/vmalloc.h>
3115+#include <linux/spinlock.h>
3116+#include <linux/smp_lock.h>
3117+#include <linux/exportfs.h>
3118+
3119+#include "squashfs.h"
3120+
3121+static struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
3122+{
3123+ struct meta_index *meta = NULL;
3124+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3125+ int i;
3126+
3127+ mutex_lock(&msblk->meta_index_mutex);
3128+
3129+ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
3130+
3131+ if (msblk->meta_index == NULL)
3132+ goto not_allocated;
3133+
3134+ for (i = 0; i < SQUASHFS_META_NUMBER; i ++) {
3135+ if (msblk->meta_index[i].inode_number == inode->i_ino &&
3136+ msblk->meta_index[i].offset >= offset &&
3137+ msblk->meta_index[i].offset <= index &&
3138+ msblk->meta_index[i].locked == 0) {
3139+ TRACE("locate_meta_index: entry %d, offset %d\n", i,
3140+ msblk->meta_index[i].offset);
3141+ meta = &msblk->meta_index[i];
3142+ offset = meta->offset;
3143+ }
3144+ }
3145+
3146+ if (meta)
3147+ meta->locked = 1;
3148+
3149+not_allocated:
3150+ mutex_unlock(&msblk->meta_index_mutex);
3151+
3152+ return meta;
3153+}
3154+
3155+
3156+static struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
3157+{
3158+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3159+ struct meta_index *meta = NULL;
3160+ int i;
3161+
3162+ mutex_lock(&msblk->meta_index_mutex);
3163+
3164+ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
3165+
3166+ if (msblk->meta_index == NULL) {
3167+ msblk->meta_index = kmalloc(sizeof(struct meta_index) *
3168+ SQUASHFS_META_NUMBER, GFP_KERNEL);
3169+ if (msblk->meta_index == NULL) {
3170+ ERROR("Failed to allocate meta_index\n");
3171+ goto failed;
3172+ }
3173+ for (i = 0; i < SQUASHFS_META_NUMBER; i++) {
3174+ msblk->meta_index[i].inode_number = 0;
3175+ msblk->meta_index[i].locked = 0;
3176+ }
3177+ msblk->next_meta_index = 0;
3178+ }
3179+
3180+ for (i = SQUASHFS_META_NUMBER; i &&
3181+ msblk->meta_index[msblk->next_meta_index].locked; i --)
3182+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
3183+ SQUASHFS_META_NUMBER;
3184+
3185+ if (i == 0) {
3186+ TRACE("empty_meta_index: failed!\n");
3187+ goto failed;
3188+ }
3189+
3190+ TRACE("empty_meta_index: returned meta entry %d, %p\n",
3191+ msblk->next_meta_index,
3192+ &msblk->meta_index[msblk->next_meta_index]);
3193+
3194+ meta = &msblk->meta_index[msblk->next_meta_index];
3195+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
3196+ SQUASHFS_META_NUMBER;
3197+
3198+ meta->inode_number = inode->i_ino;
3199+ meta->offset = offset;
3200+ meta->skip = skip;
3201+ meta->entries = 0;
3202+ meta->locked = 1;
3203+
3204+failed:
3205+ mutex_unlock(&msblk->meta_index_mutex);
3206+ return meta;
3207+}
3208+
3209+
3210+static void release_meta_index(struct inode *inode, struct meta_index *meta)
3211+{
3212+ meta->locked = 0;
3213+ smp_mb();
3214+}
3215+
3216+
3217+static int read_block_index(struct super_block *s, int blocks, char *block_list,
3218+ long long *start_block, int *offset)
3219+{
3220+ struct squashfs_sb_info *msblk = s->s_fs_info;
3221+ unsigned int *block_listp;
3222+ int block = 0;
3223+
3224+ if (msblk->swap) {
3225+ char sblock_list[blocks << 2];
3226+
3227+ if (!squashfs_get_cached_block(s, sblock_list, *start_block,
3228+ *offset, blocks << 2, start_block, offset)) {
3229+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset);
3230+ goto failure;
3231+ }
3232+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
3233+ ((unsigned int *)sblock_list), blocks);
3234+ } else {
3235+ if (!squashfs_get_cached_block(s, block_list, *start_block,
3236+ *offset, blocks << 2, start_block, offset)) {
3237+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset);
3238+ goto failure;
3239+ }
3240+ }
3241+
3242+ for (block_listp = (unsigned int *) block_list; blocks;
3243+ block_listp++, blocks --)
3244+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
3245+
3246+ return block;
3247+
3248+failure:
3249+ return -1;
3250+}
3251+
3252+
3253+#define SIZE 256
3254+
3255+static inline int calculate_skip(int blocks) {
3256+ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
3257+ return skip >= 7 ? 7 : skip + 1;
3258+}
3259+
3260+
3261+static int get_meta_index(struct inode *inode, int index,
3262+ long long *index_block, int *index_offset,
3263+ long long *data_block, char *block_list)
3264+{
3265+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3266+ struct squashfs_super_block *sblk = &msblk->sblk;
3267+ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
3268+ int offset = 0;
3269+ struct meta_index *meta;
3270+ struct meta_entry *meta_entry;
3271+ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
3272+ int cur_offset = SQUASHFS_I(inode)->offset;
3273+ long long cur_data_block = SQUASHFS_I(inode)->start_block;
3274+ int i;
3275+
3276+ index /= SQUASHFS_META_INDEXES * skip;
3277+
3278+ while (offset < index) {
3279+ meta = locate_meta_index(inode, index, offset + 1);
3280+
3281+ if (meta == NULL) {
3282+ meta = empty_meta_index(inode, offset + 1, skip);
3283+ if (meta == NULL)
3284+ goto all_done;
3285+ } else {
3286+ if(meta->entries == 0)
3287+ goto failed;
3288+ /* XXX */
3289+ offset = index < meta->offset + meta->entries ? index :
3290+ meta->offset + meta->entries - 1;
3291+ /* XXX */
3292+ meta_entry = &meta->meta_entry[offset - meta->offset];
3293+ cur_index_block = meta_entry->index_block + sblk->inode_table_start;
3294+ cur_offset = meta_entry->offset;
3295+ cur_data_block = meta_entry->data_block;
3296+ TRACE("get_meta_index: offset %d, meta->offset %d, "
3297+ "meta->entries %d\n", offset, meta->offset, meta->entries);
3298+ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
3299+ " data_block 0x%llx\n", cur_index_block,
3300+ cur_offset, cur_data_block);
3301+ }
3302+
3303+ for (i = meta->offset + meta->entries; i <= index &&
3304+ i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
3305+ int blocks = skip * SQUASHFS_META_INDEXES;
3306+
3307+ while (blocks) {
3308+ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : blocks;
3309+ int res = read_block_index(inode->i_sb, block, block_list,
3310+ &cur_index_block, &cur_offset);
3311+
3312+ if (res == -1)
3313+ goto failed;
3314+
3315+ cur_data_block += res;
3316+ blocks -= block;
3317+ }
3318+
3319+ meta_entry = &meta->meta_entry[i - meta->offset];
3320+ meta_entry->index_block = cur_index_block - sblk->inode_table_start;
3321+ meta_entry->offset = cur_offset;
3322+ meta_entry->data_block = cur_data_block;
3323+ meta->entries ++;
3324+ offset ++;
3325+ }
3326+
3327+ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
3328+ meta->offset, meta->entries);
3329+
3330+ release_meta_index(inode, meta);
3331+ }
3332+
3333+all_done:
3334+ *index_block = cur_index_block;
3335+ *index_offset = cur_offset;
3336+ *data_block = cur_data_block;
3337+
3338+ return offset * SQUASHFS_META_INDEXES * skip;
3339+
3340+failed:
3341+ release_meta_index(inode, meta);
3342+ return -1;
3343+}
3344+
3345+
3346+long long read_blocklist(struct inode *inode, int index,
3347+ int readahead_blks, char *block_list,
3348+ unsigned short **block_p, unsigned int *bsize)
3349+{
3350+ long long block_ptr;
3351+ int offset;
3352+ long long block;
3353+ int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
3354+ block_list);
3355+
3356+ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
3357+ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, block);
3358+
3359+ if(res == -1)
3360+ goto failure;
3361+
3362+ index -= res;
3363+
3364+ while (index) {
3365+ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
3366+ int res = read_block_index(inode->i_sb, blocks, block_list,
3367+ &block_ptr, &offset);
3368+ if (res == -1)
3369+ goto failure;
3370+ block += res;
3371+ index -= blocks;
3372+ }
3373+
3374+ if (read_block_index(inode->i_sb, 1, block_list, &block_ptr, &offset) == -1)
3375+ goto failure;
3376+ *bsize = *((unsigned int *) block_list);
3377+
3378+ return block;
3379+
3380+failure:
3381+ return 0;
3382+}
3383+
3384+
3385+static int squashfs_readpage(struct file *file, struct page *page)
3386+{
3387+ struct inode *inode = page->mapping->host;
3388+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3389+ struct squashfs_super_block *sblk = &msblk->sblk;
3390+ unsigned char *block_list = NULL;
3391+ long long block;
3392+ unsigned int bsize, i;
3393+ int bytes;
3394+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
3395+ void *pageaddr;
3396+ struct squashfs_cache_entry *fragment = NULL;
3397+ char *data_ptr = msblk->read_page;
3398+
3399+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
3400+ int start_index = page->index & ~mask;
3401+ int end_index = start_index | mask;
3402+ int file_end = i_size_read(inode) >> sblk->block_log;
3403+ int sparse = 0;
3404+
3405+ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
3406+ page->index, SQUASHFS_I(inode)->start_block);
3407+
3408+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
3409+ PAGE_CACHE_SHIFT))
3410+ goto out;
3411+
3412+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3413+ || index < file_end) {
3414+ block_list = kmalloc(SIZE, GFP_KERNEL);
3415+ if (block_list == NULL) {
3416+ ERROR("Failed to allocate block_list\n");
3417+ goto error_out;
3418+ }
3419+
3420+ block = (msblk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize);
3421+ if (block == 0)
3422+ goto error_out;
3423+
3424+ if (bsize == 0) { /* hole */
3425+ bytes = index == file_end ?
3426+ (i_size_read(inode) & (sblk->block_size - 1)) : sblk->block_size;
3427+ sparse = 1;
3428+ } else {
3429+ mutex_lock(&msblk->read_page_mutex);
3430+
3431+ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
3432+ bsize, NULL, sblk->block_size);
3433+
3434+ if (bytes == 0) {
3435+ ERROR("Unable to read page, block %llx, size %x\n", block, bsize);
3436+ mutex_unlock(&msblk->read_page_mutex);
3437+ goto error_out;
3438+ }
3439+ }
3440+ } else {
3441+ fragment = get_cached_fragment(inode->i_sb,
3442+ SQUASHFS_I(inode)-> u.s1.fragment_start_block,
3443+ SQUASHFS_I(inode)->u.s1.fragment_size);
3444+
3445+ if (fragment->error) {
3446+ ERROR("Unable to read page, block %llx, size %x\n",
3447+ SQUASHFS_I(inode)->u.s1.fragment_start_block,
3448+ (int) SQUASHFS_I(inode)->u.s1.fragment_size);
3449+ release_cached_fragment(msblk, fragment);
3450+ goto error_out;
3451+ }
3452+ bytes = i_size_read(inode) & (sblk->block_size - 1);
3453+ data_ptr = fragment->data + SQUASHFS_I(inode)->u.s1.fragment_offset;
3454+ }
3455+
3456+ for (i = start_index; i <= end_index && bytes > 0; i++,
3457+ bytes -= PAGE_CACHE_SIZE, data_ptr += PAGE_CACHE_SIZE) {
3458+ struct page *push_page;
3459+ int avail = sparse ? 0 : min_t(unsigned int, bytes, PAGE_CACHE_SIZE);
3460+
3461+ TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail);
3462+
3463+ push_page = (i == page->index) ? page :
3464+ grab_cache_page_nowait(page->mapping, i);
3465+
3466+ if (!push_page)
3467+ continue;
3468+
3469+ if (PageUptodate(push_page))
3470+ goto skip_page;
3471+
3472+ pageaddr = kmap_atomic(push_page, KM_USER0);
3473+ memcpy(pageaddr, data_ptr, avail);
3474+ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
3475+ kunmap_atomic(pageaddr, KM_USER0);
3476+ flush_dcache_page(push_page);
3477+ SetPageUptodate(push_page);
3478+skip_page:
3479+ unlock_page(push_page);
3480+ if(i != page->index)
3481+ page_cache_release(push_page);
3482+ }
3483+
3484+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3485+ || index < file_end) {
3486+ if (!sparse)
3487+ mutex_unlock(&msblk->read_page_mutex);
3488+ kfree(block_list);
3489+ } else
3490+ release_cached_fragment(msblk, fragment);
3491+
3492+ return 0;
3493+
3494+error_out:
3495+ SetPageError(page);
3496+out:
3497+ pageaddr = kmap_atomic(page, KM_USER0);
3498+ memset(pageaddr, 0, PAGE_CACHE_SIZE);
3499+ kunmap_atomic(pageaddr, KM_USER0);
3500+ flush_dcache_page(page);
3501+ if (!PageError(page))
3502+ SetPageUptodate(page);
3503+ unlock_page(page);
3504+
3505+ kfree(block_list);
3506+ return 0;
3507+}
3508+
3509+
3510+const struct address_space_operations squashfs_aops = {
3511+ .readpage = squashfs_readpage
3512+};
3513diff -uNr a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
3514--- a/fs/squashfs/fragment.c 1969-12-31 16:00:00.000000000 -0800
3515+++ b/fs/squashfs/fragment.c 2008-08-13 16:14:50.000000000 -0700
3516@@ -0,0 +1,122 @@
3517+/*
3518+ * Squashfs - a compressed read only filesystem for Linux
3519+ *
3520+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3521+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3522+ *
3523+ * This program is free software; you can redistribute it and/or
3524+ * modify it under the terms of the GNU General Public License
3525+ * as published by the Free Software Foundation; either version 2,
3526+ * or (at your option) any later version.
3527+ *
3528+ * This program is distributed in the hope that it will be useful,
3529+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3530+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3531+ * GNU General Public License for more details.
3532+ *
3533+ * You should have received a copy of the GNU General Public License
3534+ * along with this program; if not, write to the Free Software
3535+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3536+ *
3537+ * fragment.c
3538+ */
3539+
3540+#include <linux/squashfs_fs.h>
3541+#include <linux/module.h>
3542+#include <linux/zlib.h>
3543+#include <linux/fs.h>
3544+#include <linux/squashfs_fs_sb.h>
3545+#include <linux/squashfs_fs_i.h>
3546+#include <linux/buffer_head.h>
3547+#include <linux/vfs.h>
3548+#include <linux/vmalloc.h>
3549+#include <linux/spinlock.h>
3550+#include <linux/smp_lock.h>
3551+#include <linux/exportfs.h>
3552+
3553+#include "squashfs.h"
3554+
3555+int get_fragment_location(struct super_block *s, unsigned int fragment,
3556+ long long *fragment_start_block,
3557+ unsigned int *fragment_size)
3558+{
3559+ struct squashfs_sb_info *msblk = s->s_fs_info;
3560+ long long start_block =
3561+ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
3562+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
3563+ struct squashfs_fragment_entry fragment_entry;
3564+
3565+ if (msblk->swap) {
3566+ struct squashfs_fragment_entry sfragment_entry;
3567+
3568+ if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset,
3569+ sizeof(sfragment_entry), &start_block, &offset))
3570+ goto out;
3571+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
3572+ } else
3573+ if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset,
3574+ sizeof(fragment_entry), &start_block, &offset))
3575+ goto out;
3576+
3577+ *fragment_start_block = fragment_entry.start_block;
3578+ *fragment_size = fragment_entry.size;
3579+
3580+ return 1;
3581+
3582+out:
3583+ return 0;
3584+}
3585+
3586+
3587+void release_cached_fragment(struct squashfs_sb_info *msblk,
3588+ struct squashfs_cache_entry *fragment)
3589+{
3590+ squashfs_cache_put(msblk->fragment_cache, fragment);
3591+}
3592+
3593+
3594+struct squashfs_cache_entry *get_cached_fragment(struct super_block *s,
3595+ long long start_block, int length)
3596+{
3597+ struct squashfs_sb_info *msblk = s->s_fs_info;
3598+
3599+ return squashfs_cache_get(s, msblk->fragment_cache, start_block, length);
3600+}
3601+
3602+
3603+int read_fragment_index_table(struct super_block *s)
3604+{
3605+ struct squashfs_sb_info *msblk = s->s_fs_info;
3606+ struct squashfs_super_block *sblk = &msblk->sblk;
3607+ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments);
3608+
3609+ if(length == 0)
3610+ return 1;
3611+
3612+ /* Allocate fragment index table */
3613+ msblk->fragment_index = kmalloc(length, GFP_KERNEL);
3614+ if (msblk->fragment_index == NULL) {
3615+ ERROR("Failed to allocate fragment index table\n");
3616+ return 0;
3617+ }
3618+
3619+ if (!squashfs_read_data(s, (char *) msblk->fragment_index,
3620+ sblk->fragment_table_start, length |
3621+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3622+ ERROR("unable to read fragment index table\n");
3623+ return 0;
3624+ }
3625+
3626+ if (msblk->swap) {
3627+ int i;
3628+ long long fragment;
3629+
3630+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) {
3631+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
3632+ &msblk->fragment_index[i], 1);
3633+ msblk->fragment_index[i] = fragment;
3634+ }
3635+ }
3636+
3637+ return 1;
3638+}
3639diff -uNr a/fs/squashfs/id.c b/fs/squashfs/id.c
3640--- a/fs/squashfs/id.c 1969-12-31 16:00:00.000000000 -0800
3641+++ b/fs/squashfs/id.c 2008-08-13 16:14:50.000000000 -0700
3642@@ -0,0 +1,97 @@
3643+/*
3644+ * Squashfs - a compressed read only filesystem for Linux
3645+ *
3646+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3647+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3648+ *
3649+ * This program is free software; you can redistribute it and/or
3650+ * modify it under the terms of the GNU General Public License
3651+ * as published by the Free Software Foundation; either version 2,
3652+ * or (at your option) any later version.
3653+ *
3654+ * This program is distributed in the hope that it will be useful,
3655+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3656+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3657+ * GNU General Public License for more details.
3658+ *
3659+ * You should have received a copy of the GNU General Public License
3660+ * along with this program; if not, write to the Free Software
3661+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3662+ *
3663+ * id.c
3664+ */
3665+
3666+#include <linux/squashfs_fs.h>
3667+#include <linux/module.h>
3668+#include <linux/zlib.h>
3669+#include <linux/fs.h>
3670+#include <linux/squashfs_fs_sb.h>
3671+#include <linux/squashfs_fs_i.h>
3672+#include <linux/buffer_head.h>
3673+#include <linux/vfs.h>
3674+#include <linux/vmalloc.h>
3675+#include <linux/spinlock.h>
3676+#include <linux/smp_lock.h>
3677+#include <linux/exportfs.h>
3678+
3679+#include "squashfs.h"
3680+
3681+int get_id(struct super_block *s, unsigned int index, unsigned int *id)
3682+{
3683+ struct squashfs_sb_info *msblk = s->s_fs_info;
3684+ long long start_block = msblk->id_table[SQUASHFS_ID_BLOCK(index)];
3685+ int offset = SQUASHFS_ID_BLOCK_OFFSET(index);
3686+
3687+ if (msblk->swap) {
3688+ unsigned int sid;
3689+
3690+ if (!squashfs_get_cached_block(s, &sid, start_block, offset,
3691+ sizeof(unsigned int), &start_block, &offset))
3692+ goto out;
3693+ SQUASHFS_SWAP_INTS((&sid), id, 1);
3694+ } else
3695+ if (!squashfs_get_cached_block(s, id, start_block, offset,
3696+ sizeof(unsigned int), &start_block, &offset))
3697+ goto out;
3698+
3699+ return 1;
3700+
3701+out:
3702+ return 0;
3703+}
3704+
3705+
3706+int read_id_index_table(struct super_block *s)
3707+{
3708+ struct squashfs_sb_info *msblk = s->s_fs_info;
3709+ struct squashfs_super_block *sblk = &msblk->sblk;
3710+ unsigned int length = SQUASHFS_ID_BLOCK_BYTES(sblk->no_ids);
3711+
3712+ TRACE("In read_id_index_table, length %d\n", length);
3713+
3714+ /* Allocate id index table */
3715+ msblk->id_table = kmalloc(length, GFP_KERNEL);
3716+ if (msblk->id_table == NULL) {
3717+ ERROR("Failed to allocate id index table\n");
3718+ return 0;
3719+ }
3720+
3721+ if (!squashfs_read_data(s, (char *) msblk->id_table,
3722+ sblk->id_table_start, length |
3723+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3724+ ERROR("unable to read id index table\n");
3725+ return 0;
3726+ }
3727+
3728+ if (msblk->swap) {
3729+ int i;
3730+ long long block;
3731+
3732+ for (i = 0; i < SQUASHFS_ID_BLOCKS(sblk->no_ids); i++) {
3733+ SQUASHFS_SWAP_ID_BLOCKS((&block), &msblk->id_table[i], 1);
3734+ msblk->id_table[i] = block;
3735+ }
3736+ }
3737+
3738+ return 1;
3739+}
3740diff -uNr a/fs/squashfs/inode.c b/fs/squashfs/inode.c
3741--- a/fs/squashfs/inode.c 1969-12-31 16:00:00.000000000 -0800
3742+++ b/fs/squashfs/inode.c 2008-08-13 16:14:50.000000000 -0700
3743@@ -0,0 +1,340 @@
3744+/*
3745+ * Squashfs - a compressed read only filesystem for Linux
3746+ *
3747+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3748+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3749+ *
3750+ * This program is free software; you can redistribute it and/or
3751+ * modify it under the terms of the GNU General Public License
3752+ * as published by the Free Software Foundation; either version 2,
3753+ * or (at your option) any later version.
3754+ *
3755+ * This program is distributed in the hope that it will be useful,
3756+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3757+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3758+ * GNU General Public License for more details.
3759+ *
3760+ * You should have received a copy of the GNU General Public License
3761+ * along with this program; if not, write to the Free Software
3762+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3763+ *
3764+ * inode.c
3765+ */
3766+
3767+#include <linux/squashfs_fs.h>
3768+#include <linux/module.h>
3769+#include <linux/zlib.h>
3770+#include <linux/fs.h>
3771+#include <linux/squashfs_fs_sb.h>
3772+#include <linux/squashfs_fs_i.h>
3773+#include <linux/buffer_head.h>
3774+#include <linux/vfs.h>
3775+#include <linux/vmalloc.h>
3776+#include <linux/spinlock.h>
3777+#include <linux/smp_lock.h>
3778+#include <linux/exportfs.h>
3779+
3780+#include "squashfs.h"
3781+
3782+static int squashfs_new_inode(struct super_block *s, struct inode *i,
3783+ struct squashfs_base_inode_header *inodeb)
3784+{
3785+ if(get_id(s, inodeb->uid, &i->i_uid) == 0)
3786+ goto out;
3787+ if(get_id(s, inodeb->guid, &i->i_gid) == 0)
3788+ goto out;
3789+
3790+ i->i_ino = inodeb->inode_number;
3791+ i->i_mtime.tv_sec = inodeb->mtime;
3792+ i->i_atime.tv_sec = inodeb->mtime;
3793+ i->i_ctime.tv_sec = inodeb->mtime;
3794+ i->i_mode = inodeb->mode;
3795+ i->i_size = 0;
3796+
3797+ return 1;
3798+
3799+out:
3800+ return 0;
3801+}
3802+
3803+
3804+struct inode *squashfs_iget(struct super_block *s,
3805+ squashfs_inode_t inode, unsigned int inode_number)
3806+{
3807+ struct squashfs_sb_info *msblk = s->s_fs_info;
3808+ struct inode *i = iget_locked(s, inode_number);
3809+
3810+ TRACE("Entered squashfs_iget\n");
3811+
3812+ if(i && (i->i_state & I_NEW)) {
3813+ (msblk->read_inode)(i, inode);
3814+ unlock_new_inode(i);
3815+ }
3816+
3817+ return i;
3818+}
3819+
3820+
3821+int squashfs_read_inode(struct inode *i, squashfs_inode_t inode)
3822+{
3823+ struct super_block *s = i->i_sb;
3824+ struct squashfs_sb_info *msblk = s->s_fs_info;
3825+ struct squashfs_super_block *sblk = &msblk->sblk;
3826+ long long block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start;
3827+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
3828+ long long next_block;
3829+ unsigned int next_offset;
3830+ union squashfs_inode_header id, sid;
3831+ struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base;
3832+
3833+ TRACE("Entered squashfs_read_inode\n");
3834+
3835+ if (msblk->swap) {
3836+ if (!squashfs_get_cached_block(s, sinodeb, block, offset,
3837+ sizeof(*sinodeb), &next_block, &next_offset))
3838+ goto failed_read;
3839+ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, sizeof(*sinodeb));
3840+ } else
3841+ if (!squashfs_get_cached_block(s, inodeb, block, offset,
3842+ sizeof(*inodeb), &next_block, &next_offset))
3843+ goto failed_read;
3844+
3845+ if(squashfs_new_inode(s, i, inodeb) == 0)
3846+ goto failed_read;
3847+
3848+ switch(inodeb->inode_type) {
3849+ case SQUASHFS_FILE_TYPE: {
3850+ unsigned int frag_size;
3851+ long long frag_blk;
3852+ struct squashfs_reg_inode_header *inodep = &id.reg;
3853+ struct squashfs_reg_inode_header *sinodep = &sid.reg;
3854+
3855+ if (msblk->swap) {
3856+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3857+ sizeof(*sinodep), &next_block, &next_offset))
3858+ goto failed_read;
3859+ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
3860+ } else
3861+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3862+ sizeof(*inodep), &next_block, &next_offset))
3863+ goto failed_read;
3864+
3865+ frag_blk = SQUASHFS_INVALID_BLK;
3866+
3867+ if (inodep->fragment != SQUASHFS_INVALID_FRAG)
3868+ if(!get_fragment_location(s, inodep->fragment, &frag_blk,
3869+ &frag_size))
3870+ goto failed_read;
3871+
3872+ i->i_nlink = 1;
3873+ i->i_size = inodep->file_size;
3874+ i->i_fop = &generic_ro_fops;
3875+ i->i_mode |= S_IFREG;
3876+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
3877+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3878+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3879+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3880+ SQUASHFS_I(i)->start_block = inodep->start_block;
3881+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3882+ SQUASHFS_I(i)->offset = next_offset;
3883+ i->i_data.a_ops = &squashfs_aops;
3884+
3885+ TRACE("File inode %x:%x, start_block %llx, "
3886+ "block_list_start %llx, offset %x\n",
3887+ SQUASHFS_INODE_BLK(inode), offset,
3888+ inodep->start_block, next_block,
3889+ next_offset);
3890+ break;
3891+ }
3892+ case SQUASHFS_LREG_TYPE: {
3893+ unsigned int frag_size;
3894+ long long frag_blk;
3895+ struct squashfs_lreg_inode_header *inodep = &id.lreg;
3896+ struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
3897+
3898+ if (msblk->swap) {
3899+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3900+ sizeof(*sinodep), &next_block, &next_offset))
3901+ goto failed_read;
3902+ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
3903+ } else
3904+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3905+ sizeof(*inodep), &next_block, &next_offset))
3906+ goto failed_read;
3907+
3908+ frag_blk = SQUASHFS_INVALID_BLK;
3909+
3910+ if (inodep->fragment != SQUASHFS_INVALID_FRAG)
3911+ if (!get_fragment_location(s, inodep->fragment, &frag_blk,
3912+ &frag_size))
3913+ goto failed_read;
3914+
3915+ i->i_nlink = inodep->nlink;
3916+ i->i_size = inodep->file_size;
3917+ i->i_fop = &generic_ro_fops;
3918+ i->i_mode |= S_IFREG;
3919+ i->i_blocks = ((inodep->file_size - inodep->sparse - 1) >> 9) + 1;
3920+
3921+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3922+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3923+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3924+ SQUASHFS_I(i)->start_block = inodep->start_block;
3925+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3926+ SQUASHFS_I(i)->offset = next_offset;
3927+ i->i_data.a_ops = &squashfs_aops;
3928+
3929+ TRACE("File inode %x:%x, start_block %llx, "
3930+ "block_list_start %llx, offset %x\n",
3931+ SQUASHFS_INODE_BLK(inode), offset,
3932+ inodep->start_block, next_block,
3933+ next_offset);
3934+ break;
3935+ }
3936+ case SQUASHFS_DIR_TYPE: {
3937+ struct squashfs_dir_inode_header *inodep = &id.dir;
3938+ struct squashfs_dir_inode_header *sinodep = &sid.dir;
3939+
3940+ if (msblk->swap) {
3941+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3942+ sizeof(*sinodep), &next_block, &next_offset))
3943+ goto failed_read;
3944+ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
3945+ } else
3946+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3947+ sizeof(*inodep), &next_block, &next_offset))
3948+ goto failed_read;
3949+
3950+ i->i_nlink = inodep->nlink;
3951+ i->i_size = inodep->file_size;
3952+ i->i_op = &squashfs_dir_inode_ops;
3953+ i->i_fop = &squashfs_dir_ops;
3954+ i->i_mode |= S_IFDIR;
3955+ SQUASHFS_I(i)->start_block = inodep->start_block;
3956+ SQUASHFS_I(i)->offset = inodep->offset;
3957+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
3958+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
3959+
3960+ TRACE("Directory inode %x:%x, start_block %x, offset "
3961+ "%x\n", SQUASHFS_INODE_BLK(inode),
3962+ offset, inodep->start_block,
3963+ inodep->offset);
3964+ break;
3965+ }
3966+ case SQUASHFS_LDIR_TYPE: {
3967+ struct squashfs_ldir_inode_header *inodep = &id.ldir;
3968+ struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
3969+
3970+ if (msblk->swap) {
3971+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3972+ sizeof(*sinodep), &next_block, &next_offset))
3973+ goto failed_read;
3974+ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, sinodep);
3975+ } else
3976+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3977+ sizeof(*inodep), &next_block, &next_offset))
3978+ goto failed_read;
3979+
3980+ i->i_nlink = inodep->nlink;
3981+ i->i_size = inodep->file_size;
3982+ i->i_op = &squashfs_dir_inode_ops;
3983+ i->i_fop = &squashfs_dir_ops;
3984+ i->i_mode |= S_IFDIR;
3985+ SQUASHFS_I(i)->start_block = inodep->start_block;
3986+ SQUASHFS_I(i)->offset = inodep->offset;
3987+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
3988+ SQUASHFS_I(i)->u.s2.directory_index_offset = next_offset;
3989+ SQUASHFS_I(i)->u.s2.directory_index_count = inodep->i_count;
3990+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
3991+
3992+ TRACE("Long directory inode %x:%x, start_block %x, offset %x\n",
3993+ SQUASHFS_INODE_BLK(inode), offset,
3994+ inodep->start_block, inodep->offset);
3995+ break;
3996+ }
3997+ case SQUASHFS_SYMLINK_TYPE: {
3998+ struct squashfs_symlink_inode_header *inodep = &id.symlink;
3999+ struct squashfs_symlink_inode_header *sinodep = &sid.symlink;
4000+
4001+ if (msblk->swap) {
4002+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4003+ sizeof(*sinodep), &next_block, &next_offset))
4004+ goto failed_read;
4005+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, sinodep);
4006+ } else
4007+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4008+ sizeof(*inodep), &next_block, &next_offset))
4009+ goto failed_read;
4010+
4011+ i->i_nlink = inodep->nlink;
4012+ i->i_size = inodep->symlink_size;
4013+ i->i_op = &page_symlink_inode_operations;
4014+ i->i_data.a_ops = &squashfs_symlink_aops;
4015+ i->i_mode |= S_IFLNK;
4016+ SQUASHFS_I(i)->start_block = next_block;
4017+ SQUASHFS_I(i)->offset = next_offset;
4018+
4019+ TRACE("Symbolic link inode %x:%x, start_block %llx, offset %x\n",
4020+ SQUASHFS_INODE_BLK(inode), offset,
4021+ next_block, next_offset);
4022+ break;
4023+ }
4024+ case SQUASHFS_BLKDEV_TYPE:
4025+ case SQUASHFS_CHRDEV_TYPE: {
4026+ struct squashfs_dev_inode_header *inodep = &id.dev;
4027+ struct squashfs_dev_inode_header *sinodep = &sid.dev;
4028+
4029+ if (msblk->swap) {
4030+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4031+ sizeof(*sinodep), &next_block, &next_offset))
4032+ goto failed_read;
4033+ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
4034+ } else
4035+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4036+ sizeof(*inodep), &next_block, &next_offset))
4037+ goto failed_read;
4038+
4039+ i->i_nlink = inodep->nlink;
4040+ i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ?
4041+ S_IFCHR : S_IFBLK;
4042+ init_special_inode(i, i->i_mode, old_decode_dev(inodep->rdev));
4043+
4044+ TRACE("Device inode %x:%x, rdev %x\n",
4045+ SQUASHFS_INODE_BLK(inode), offset, inodep->rdev);
4046+ break;
4047+ }
4048+ case SQUASHFS_FIFO_TYPE:
4049+ case SQUASHFS_SOCKET_TYPE: {
4050+ struct squashfs_ipc_inode_header *inodep = &id.ipc;
4051+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
4052+
4053+ if (msblk->swap) {
4054+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4055+ sizeof(*sinodep), &next_block, &next_offset))
4056+ goto failed_read;
4057+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
4058+ } else
4059+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4060+ sizeof(*inodep), &next_block, &next_offset))
4061+ goto failed_read;
4062+
4063+ i->i_nlink = inodep->nlink;
4064+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4065+ ? S_IFIFO : S_IFSOCK;
4066+ init_special_inode(i, i->i_mode, 0);
4067+ break;
4068+ }
4069+ default:
4070+ ERROR("Unknown inode type %d in squashfs_iget!\n",
4071+ inodeb->inode_type);
4072+ goto failed_read1;
4073+ }
4074+
4075+ return 1;
4076+
4077+failed_read:
4078+ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
4079+
4080+failed_read1:
4081+ make_bad_inode(i);
4082+ return 0;
4083+}
4084diff -uNr a/fs/squashfs/Makefile b/fs/squashfs/Makefile
4085--- a/fs/squashfs/Makefile 1969-12-31 16:00:00.000000000 -0800
4086+++ b/fs/squashfs/Makefile 2008-08-13 16:14:50.000000000 -0700
4087@@ -0,0 +1,8 @@
4088+#
4089+# Makefile for the linux squashfs routines.
4090+#
4091+
4092+obj-$(CONFIG_SQUASHFS) += squashfs.o
4093+squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
4094+squashfs-y += namei.o super.o symlink.o
4095+#squashfs-y += squashfs2_0.o
4096diff -uNr a/fs/squashfs/namei.c b/fs/squashfs/namei.c
4097--- a/fs/squashfs/namei.c 1969-12-31 16:00:00.000000000 -0800
4098+++ b/fs/squashfs/namei.c 2008-08-13 16:14:50.000000000 -0700
4099@@ -0,0 +1,200 @@
4100+/*
4101+ * Squashfs - a compressed read only filesystem for Linux
4102+ *
4103+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4104+ * Phillip Lougher <phillip@lougher.demon.co.uk>
4105+ *
4106+ * This program is free software; you can redistribute it and/or
4107+ * modify it under the terms of the GNU General Public License
4108+ * as published by the Free Software Foundation; either version 2,
4109+ * or (at your option) any later version.
4110+ *
4111+ * This program is distributed in the hope that it will be useful,
4112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4114+ * GNU General Public License for more details.
4115+ *
4116+ * You should have received a copy of the GNU General Public License
4117+ * along with this program; if not, write to the Free Software
4118+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4119+ *
4120+ * namei.c
4121+ */
4122+
4123+#include <linux/squashfs_fs.h>
4124+#include <linux/module.h>
4125+#include <linux/zlib.h>
4126+#include <linux/fs.h>
4127+#include <linux/squashfs_fs_sb.h>
4128+#include <linux/squashfs_fs_i.h>
4129+#include <linux/buffer_head.h>
4130+#include <linux/vfs.h>
4131+#include <linux/vmalloc.h>
4132+#include <linux/spinlock.h>
4133+#include <linux/smp_lock.h>
4134+#include <linux/exportfs.h>
4135+
4136+#include "squashfs.h"
4137+
4138+static int get_dir_index_using_name(struct super_block *s,
4139+ long long *next_block, unsigned int *next_offset,
4140+ long long index_start, unsigned int index_offset, int i_count,
4141+ const char *name, int size)
4142+{
4143+ struct squashfs_sb_info *msblk = s->s_fs_info;
4144+ struct squashfs_super_block *sblk = &msblk->sblk;
4145+ int i, length = 0;
4146+ struct squashfs_dir_index *index;
4147+ char *str;
4148+
4149+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4150+
4151+ str = kmalloc(sizeof(struct squashfs_dir_index) +
4152+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL);
4153+ if (str == NULL) {
4154+ ERROR("Failed to allocate squashfs_dir_index\n");
4155+ goto failure;
4156+ }
4157+
4158+ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1);
4159+ strncpy(str, name, size);
4160+ str[size] = '\0';
4161+
4162+ for (i = 0; i < i_count; i++) {
4163+ if (msblk->swap) {
4164+ struct squashfs_dir_index sindex;
4165+ squashfs_get_cached_block(s, &sindex, index_start, index_offset,
4166+ sizeof(sindex), &index_start, &index_offset);
4167+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
4168+ } else
4169+ squashfs_get_cached_block(s, index, index_start, index_offset,
4170+ sizeof(struct squashfs_dir_index), &index_start, &index_offset);
4171+
4172+ squashfs_get_cached_block(s, index->name, index_start, index_offset,
4173+ index->size + 1, &index_start, &index_offset);
4174+
4175+ index->name[index->size + 1] = '\0';
4176+
4177+ if (strcmp(index->name, str) > 0)
4178+ break;
4179+
4180+ length = index->index;
4181+ *next_block = index->start_block + sblk->directory_table_start;
4182+ }
4183+
4184+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4185+ kfree(str);
4186+
4187+failure:
4188+ return length + 3;
4189+}
4190+
4191+
4192+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
4193+ struct nameidata *nd)
4194+{
4195+ const unsigned char *name = dentry->d_name.name;
4196+ int len = dentry->d_name.len;
4197+ struct inode *inode = NULL;
4198+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4199+ struct squashfs_super_block *sblk = &msblk->sblk;
4200+ long long next_block = SQUASHFS_I(i)->start_block +
4201+ sblk->directory_table_start;
4202+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count;
4203+ struct squashfs_dir_header dirh;
4204+ struct squashfs_dir_entry *dire;
4205+
4206+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
4207+
4208+ dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4209+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
4210+ if (dire == NULL) {
4211+ ERROR("Failed to allocate squashfs_dir_entry\n");
4212+ goto exit_lookup;
4213+ }
4214+
4215+ if (len > SQUASHFS_NAME_LEN)
4216+ goto exit_lookup;
4217+
4218+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4219+ SQUASHFS_I(i)->u.s2.directory_index_start,
4220+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4221+ SQUASHFS_I(i)->u.s2.directory_index_count, name, len);
4222+
4223+ while (length < i_size_read(i)) {
4224+ /* read directory header */
4225+ if (msblk->swap) {
4226+ struct squashfs_dir_header sdirh;
4227+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block,
4228+ next_offset, sizeof(sdirh), &next_block, &next_offset))
4229+ goto failed_read;
4230+
4231+ length += sizeof(sdirh);
4232+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
4233+ } else {
4234+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block,
4235+ next_offset, sizeof(dirh), &next_block, &next_offset))
4236+ goto failed_read;
4237+
4238+ length += sizeof(dirh);
4239+ }
4240+
4241+ dir_count = dirh.count + 1;
4242+ while (dir_count--) {
4243+ if (msblk->swap) {
4244+ struct squashfs_dir_entry sdire;
4245+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block,
4246+ next_offset, sizeof(sdire), &next_block, &next_offset))
4247+ goto failed_read;
4248+
4249+ length += sizeof(sdire);
4250+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
4251+ } else {
4252+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block,
4253+ next_offset, sizeof(*dire), &next_block, &next_offset))
4254+ goto failed_read;
4255+
4256+ length += sizeof(*dire);
4257+ }
4258+
4259+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block,
4260+ next_offset, dire->size + 1, &next_block, &next_offset))
4261+ goto failed_read;
4262+
4263+ length += dire->size + 1;
4264+
4265+ if (name[0] < dire->name[0])
4266+ goto exit_lookup;
4267+
4268+ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) {
4269+ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block,
4270+ dire->offset);
4271+
4272+ TRACE("calling squashfs_iget for directory entry %s, inode"
4273+ " %x:%x, %d\n", name, dirh.start_block, dire->offset,
4274+ dirh.inode_number + dire->inode_number);
4275+
4276+ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number);
4277+
4278+ goto exit_lookup;
4279+ }
4280+ }
4281+ }
4282+
4283+exit_lookup:
4284+ kfree(dire);
4285+ if (inode)
4286+ return d_splice_alias(inode, dentry);
4287+ d_add(dentry, inode);
4288+ return ERR_PTR(0);
4289+
4290+failed_read:
4291+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4292+ next_offset);
4293+ goto exit_lookup;
4294+}
4295+
4296+
4297+const struct inode_operations squashfs_dir_inode_ops = {
4298+ .lookup = squashfs_lookup
4299+};
4300diff -uNr a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c
4301--- a/fs/squashfs/squashfs2_0.c 1969-12-31 16:00:00.000000000 -0800
4302+++ b/fs/squashfs/squashfs2_0.c 2008-08-13 16:14:50.000000000 -0700
4303@@ -0,0 +1,740 @@
4304+/*
4305+ * Squashfs - a compressed read only filesystem for Linux
4306+ *
4307+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4308+ * Phillip Lougher <phillip@lougher.demon.co.uk>
4309+ *
4310+ * This program is free software; you can redistribute it and/or
4311+ * modify it under the terms of the GNU General Public License
4312+ * as published by the Free Software Foundation; either version 2,
4313+ * or (at your option) any later version.
4314+ *
4315+ * This program is distributed in the hope that it will be useful,
4316+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4317+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4318+ * GNU General Public License for more details.
4319+ *
4320+ * You should have received a copy of the GNU General Public License
4321+ * along with this program; if not, write to the Free Software
4322+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4323+ *
4324+ * squashfs2_0.c
4325+ */
4326+
4327+#include <linux/squashfs_fs.h>
4328+#include <linux/module.h>
4329+#include <linux/zlib.h>
4330+#include <linux/fs.h>
4331+#include <linux/squashfs_fs_sb.h>
4332+#include <linux/squashfs_fs_i.h>
4333+
4334+#include "squashfs.h"
4335+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
4336+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
4337+ struct nameidata *);
4338+
4339+static struct file_operations squashfs_dir_ops_2 = {
4340+ .read = generic_read_dir,
4341+ .readdir = squashfs_readdir_2
4342+};
4343+
4344+static struct inode_operations squashfs_dir_inode_ops_2 = {
4345+ .lookup = squashfs_lookup_2
4346+};
4347+
4348+static unsigned char squashfs_filetype_table[] = {
4349+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
4350+};
4351+
4352+static int read_fragment_index_table_2(struct super_block *s)
4353+{
4354+ struct squashfs_sb_info *msblk = s->s_fs_info;
4355+ struct squashfs_super_block *sblk = &msblk->sblk;
4356+
4357+ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
4358+ (sblk->fragments), GFP_KERNEL))) {
4359+ ERROR("Failed to allocate uid/gid table\n");
4360+ return 0;
4361+ }
4362+
4363+ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
4364+ !squashfs_read_data(s, (char *)
4365+ msblk->fragment_index_2,
4366+ sblk->fragment_table_start,
4367+ SQUASHFS_FRAGMENT_INDEX_BYTES_2
4368+ (sblk->fragments) |
4369+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) {
4370+ ERROR("unable to read fragment index table\n");
4371+ return 0;
4372+ }
4373+
4374+ if (msblk->swap) {
4375+ int i;
4376+ unsigned int fragment;
4377+
4378+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
4379+ i++) {
4380+ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
4381+ &msblk->fragment_index_2[i], 1);
4382+ msblk->fragment_index_2[i] = fragment;
4383+ }
4384+ }
4385+
4386+ return 1;
4387+}
4388+
4389+
4390+static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
4391+ long long *fragment_start_block,
4392+ unsigned int *fragment_size)
4393+{
4394+ struct squashfs_sb_info *msblk = s->s_fs_info;
4395+ long long start_block =
4396+ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
4397+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
4398+ struct squashfs_fragment_entry_2 fragment_entry;
4399+
4400+ if (msblk->swap) {
4401+ struct squashfs_fragment_entry_2 sfragment_entry;
4402+
4403+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
4404+ start_block, offset,
4405+ sizeof(sfragment_entry), &start_block,
4406+ &offset))
4407+ goto out;
4408+ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
4409+ } else
4410+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
4411+ start_block, offset,
4412+ sizeof(fragment_entry), &start_block,
4413+ &offset))
4414+ goto out;
4415+
4416+ *fragment_start_block = fragment_entry.start_block;
4417+ *fragment_size = fragment_entry.size;
4418+
4419+ return 1;
4420+
4421+out:
4422+ return 0;
4423+}
4424+
4425+
4426+static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
4427+ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
4428+{
4429+ struct squashfs_super_block *sblk = &msblk->sblk;
4430+
4431+ i->i_ino = ino;
4432+ i->i_mtime.tv_sec = sblk->mkfs_time;
4433+ i->i_atime.tv_sec = sblk->mkfs_time;
4434+ i->i_ctime.tv_sec = sblk->mkfs_time;
4435+ i->i_uid = msblk->uid[inodeb->uid];
4436+ i->i_mode = inodeb->mode;
4437+ i->i_nlink = 1;
4438+ i->i_size = 0;
4439+ if (inodeb->guid == SQUASHFS_GUIDS)
4440+ i->i_gid = i->i_uid;
4441+ else
4442+ i->i_gid = msblk->guid[inodeb->guid];
4443+}
4444+
4445+
4446+static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode)
4447+{
4448+ struct super_block *s = i->i_sb;
4449+ struct squashfs_sb_info *msblk = s->s_fs_info;
4450+ struct squashfs_super_block *sblk = &msblk->sblk;
4451+ unsigned int block = SQUASHFS_INODE_BLK(inode) +
4452+ sblk->inode_table_start;
4453+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
4454+ unsigned int ino = SQUASHFS_MK_VFS_INODE(block -
4455+ sblk->inode_table_start, offset);
4456+ long long next_block;
4457+ unsigned int next_offset;
4458+ union squashfs_inode_header_2 id, sid;
4459+ struct squashfs_base_inode_header_2 *inodeb = &id.base,
4460+ *sinodeb = &sid.base;
4461+
4462+ TRACE("Entered squashfs_read_inode_2\n");
4463+
4464+ if (msblk->swap) {
4465+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
4466+ offset, sizeof(*sinodeb), &next_block,
4467+ &next_offset))
4468+ goto failed_read;
4469+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
4470+ sizeof(*sinodeb));
4471+ } else
4472+ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
4473+ offset, sizeof(*inodeb), &next_block,
4474+ &next_offset))
4475+ goto failed_read;
4476+
4477+ squashfs_new_inode(msblk, i, inodeb, ino);
4478+
4479+ switch(inodeb->inode_type) {
4480+ case SQUASHFS_FILE_TYPE: {
4481+ struct squashfs_reg_inode_header_2 *inodep = &id.reg;
4482+ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
4483+ long long frag_blk;
4484+ unsigned int frag_size = 0;
4485+
4486+ if (msblk->swap) {
4487+ if (!squashfs_get_cached_block(s, (char *)
4488+ sinodep, block, offset,
4489+ sizeof(*sinodep), &next_block,
4490+ &next_offset))
4491+ goto failed_read;
4492+ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
4493+ } else
4494+ if (!squashfs_get_cached_block(s, (char *)
4495+ inodep, block, offset,
4496+ sizeof(*inodep), &next_block,
4497+ &next_offset))
4498+ goto failed_read;
4499+
4500+ frag_blk = SQUASHFS_INVALID_BLK;
4501+ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
4502+ !get_fragment_location_2(s,
4503+ inodep->fragment, &frag_blk, &frag_size))
4504+ goto failed_read;
4505+
4506+ i->i_size = inodep->file_size;
4507+ i->i_fop = &generic_ro_fops;
4508+ i->i_mode |= S_IFREG;
4509+ i->i_mtime.tv_sec = inodep->mtime;
4510+ i->i_atime.tv_sec = inodep->mtime;
4511+ i->i_ctime.tv_sec = inodep->mtime;
4512+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
4513+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
4514+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
4515+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
4516+ SQUASHFS_I(i)->start_block = inodep->start_block;
4517+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
4518+ SQUASHFS_I(i)->offset = next_offset;
4519+ i->i_data.a_ops = &squashfs_aops;
4520+
4521+ TRACE("File inode %x:%x, start_block %x, "
4522+ "block_list_start %llx, offset %x\n",
4523+ SQUASHFS_INODE_BLK(inode), offset,
4524+ inodep->start_block, next_block,
4525+ next_offset);
4526+ break;
4527+ }
4528+ case SQUASHFS_DIR_TYPE: {
4529+ struct squashfs_dir_inode_header_2 *inodep = &id.dir;
4530+ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
4531+
4532+ if (msblk->swap) {
4533+ if (!squashfs_get_cached_block(s, (char *)
4534+ sinodep, block, offset,
4535+ sizeof(*sinodep), &next_block,
4536+ &next_offset))
4537+ goto failed_read;
4538+ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
4539+ } else
4540+ if (!squashfs_get_cached_block(s, (char *)
4541+ inodep, block, offset,
4542+ sizeof(*inodep), &next_block,
4543+ &next_offset))
4544+ goto failed_read;
4545+
4546+ i->i_size = inodep->file_size;
4547+ i->i_op = &squashfs_dir_inode_ops_2;
4548+ i->i_fop = &squashfs_dir_ops_2;
4549+ i->i_mode |= S_IFDIR;
4550+ i->i_mtime.tv_sec = inodep->mtime;
4551+ i->i_atime.tv_sec = inodep->mtime;
4552+ i->i_ctime.tv_sec = inodep->mtime;
4553+ SQUASHFS_I(i)->start_block = inodep->start_block;
4554+ SQUASHFS_I(i)->offset = inodep->offset;
4555+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
4556+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4557+
4558+ TRACE("Directory inode %x:%x, start_block %x, offset "
4559+ "%x\n", SQUASHFS_INODE_BLK(inode),
4560+ offset, inodep->start_block,
4561+ inodep->offset);
4562+ break;
4563+ }
4564+ case SQUASHFS_LDIR_TYPE: {
4565+ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
4566+ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
4567+
4568+ if (msblk->swap) {
4569+ if (!squashfs_get_cached_block(s, (char *)
4570+ sinodep, block, offset,
4571+ sizeof(*sinodep), &next_block,
4572+ &next_offset))
4573+ goto failed_read;
4574+ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
4575+ sinodep);
4576+ } else
4577+ if (!squashfs_get_cached_block(s, (char *)
4578+ inodep, block, offset,
4579+ sizeof(*inodep), &next_block,
4580+ &next_offset))
4581+ goto failed_read;
4582+
4583+ i->i_size = inodep->file_size;
4584+ i->i_op = &squashfs_dir_inode_ops_2;
4585+ i->i_fop = &squashfs_dir_ops_2;
4586+ i->i_mode |= S_IFDIR;
4587+ i->i_mtime.tv_sec = inodep->mtime;
4588+ i->i_atime.tv_sec = inodep->mtime;
4589+ i->i_ctime.tv_sec = inodep->mtime;
4590+ SQUASHFS_I(i)->start_block = inodep->start_block;
4591+ SQUASHFS_I(i)->offset = inodep->offset;
4592+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
4593+ SQUASHFS_I(i)->u.s2.directory_index_offset =
4594+ next_offset;
4595+ SQUASHFS_I(i)->u.s2.directory_index_count =
4596+ inodep->i_count;
4597+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4598+
4599+ TRACE("Long directory inode %x:%x, start_block %x, "
4600+ "offset %x\n",
4601+ SQUASHFS_INODE_BLK(inode), offset,
4602+ inodep->start_block, inodep->offset);
4603+ break;
4604+ }
4605+ case SQUASHFS_SYMLINK_TYPE: {
4606+ struct squashfs_symlink_inode_header_2 *inodep =
4607+ &id.symlink;
4608+ struct squashfs_symlink_inode_header_2 *sinodep =
4609+ &sid.symlink;
4610+
4611+ if (msblk->swap) {
4612+ if (!squashfs_get_cached_block(s, (char *)
4613+ sinodep, block, offset,
4614+ sizeof(*sinodep), &next_block,
4615+ &next_offset))
4616+ goto failed_read;
4617+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
4618+ sinodep);
4619+ } else
4620+ if (!squashfs_get_cached_block(s, (char *)
4621+ inodep, block, offset,
4622+ sizeof(*inodep), &next_block,
4623+ &next_offset))
4624+ goto failed_read;
4625+
4626+ i->i_size = inodep->symlink_size;
4627+ i->i_op = &page_symlink_inode_operations;
4628+ i->i_data.a_ops = &squashfs_symlink_aops;
4629+ i->i_mode |= S_IFLNK;
4630+ SQUASHFS_I(i)->start_block = next_block;
4631+ SQUASHFS_I(i)->offset = next_offset;
4632+
4633+ TRACE("Symbolic link inode %x:%x, start_block %llx, "
4634+ "offset %x\n",
4635+ SQUASHFS_INODE_BLK(inode), offset,
4636+ next_block, next_offset);
4637+ break;
4638+ }
4639+ case SQUASHFS_BLKDEV_TYPE:
4640+ case SQUASHFS_CHRDEV_TYPE: {
4641+ struct squashfs_dev_inode_header_2 *inodep = &id.dev;
4642+ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
4643+
4644+ if (msblk->swap) {
4645+ if (!squashfs_get_cached_block(s, (char *)
4646+ sinodep, block, offset,
4647+ sizeof(*sinodep), &next_block,
4648+ &next_offset))
4649+ goto failed_read;
4650+ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
4651+ } else
4652+ if (!squashfs_get_cached_block(s, (char *)
4653+ inodep, block, offset,
4654+ sizeof(*inodep), &next_block,
4655+ &next_offset))
4656+ goto failed_read;
4657+
4658+ i->i_mode |= (inodeb->inode_type ==
4659+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
4660+ S_IFBLK;
4661+ init_special_inode(i, i->i_mode,
4662+ old_decode_dev(inodep->rdev));
4663+
4664+ TRACE("Device inode %x:%x, rdev %x\n",
4665+ SQUASHFS_INODE_BLK(inode), offset,
4666+ inodep->rdev);
4667+ break;
4668+ }
4669+ case SQUASHFS_FIFO_TYPE:
4670+ case SQUASHFS_SOCKET_TYPE: {
4671+
4672+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4673+ ? S_IFIFO : S_IFSOCK;
4674+ init_special_inode(i, i->i_mode, 0);
4675+ break;
4676+ }
4677+ default:
4678+ ERROR("Unknown inode type %d in squashfs_iget!\n",
4679+ inodeb->inode_type);
4680+ goto failed_read1;
4681+ }
4682+
4683+ return 1;
4684+
4685+failed_read:
4686+ ERROR("Unable to read inode [%x:%x]\n", block, offset);
4687+
4688+failed_read1:
4689+ return 0;
4690+}
4691+
4692+
4693+static int get_dir_index_using_offset(struct super_block *s, long long
4694+ *next_block, unsigned int *next_offset,
4695+ long long index_start,
4696+ unsigned int index_offset, int i_count,
4697+ long long f_pos)
4698+{
4699+ struct squashfs_sb_info *msblk = s->s_fs_info;
4700+ struct squashfs_super_block *sblk = &msblk->sblk;
4701+ int i, length = 0;
4702+ struct squashfs_dir_index_2 index;
4703+
4704+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
4705+ i_count, (unsigned int) f_pos);
4706+
4707+ if (f_pos == 0)
4708+ goto finish;
4709+
4710+ for (i = 0; i < i_count; i++) {
4711+ if (msblk->swap) {
4712+ struct squashfs_dir_index_2 sindex;
4713+ squashfs_get_cached_block(s, (char *) &sindex,
4714+ index_start, index_offset,
4715+ sizeof(sindex), &index_start,
4716+ &index_offset);
4717+ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
4718+ } else
4719+ squashfs_get_cached_block(s, (char *) &index,
4720+ index_start, index_offset,
4721+ sizeof(index), &index_start,
4722+ &index_offset);
4723+
4724+ if (index.index > f_pos)
4725+ break;
4726+
4727+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
4728+ index.size + 1, &index_start,
4729+ &index_offset);
4730+
4731+ length = index.index;
4732+ *next_block = index.start_block + sblk->directory_table_start;
4733+ }
4734+
4735+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4736+
4737+finish:
4738+ return length;
4739+}
4740+
4741+
4742+static int get_dir_index_using_name(struct super_block *s, long long
4743+ *next_block, unsigned int *next_offset,
4744+ long long index_start,
4745+ unsigned int index_offset, int i_count,
4746+ const char *name, int size)
4747+{
4748+ struct squashfs_sb_info *msblk = s->s_fs_info;
4749+ struct squashfs_super_block *sblk = &msblk->sblk;
4750+ int i, length = 0;
4751+ struct squashfs_dir_index_2 *index;
4752+ char *str;
4753+
4754+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4755+
4756+ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
4757+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
4758+ ERROR("Failed to allocate squashfs_dir_index\n");
4759+ goto failure;
4760+ }
4761+
4762+ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1);
4763+ strncpy(str, name, size);
4764+ str[size] = '\0';
4765+
4766+ for (i = 0; i < i_count; i++) {
4767+ if (msblk->swap) {
4768+ struct squashfs_dir_index_2 sindex;
4769+ squashfs_get_cached_block(s, (char *) &sindex,
4770+ index_start, index_offset,
4771+ sizeof(sindex), &index_start,
4772+ &index_offset);
4773+ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
4774+ } else
4775+ squashfs_get_cached_block(s, (char *) index,
4776+ index_start, index_offset,
4777+ sizeof(struct squashfs_dir_index_2),
4778+ &index_start, &index_offset);
4779+
4780+ squashfs_get_cached_block(s, index->name, index_start,
4781+ index_offset, index->size + 1,
4782+ &index_start, &index_offset);
4783+
4784+ index->name[index->size + 1] = '\0';
4785+
4786+ if (strcmp(index->name, str) > 0)
4787+ break;
4788+
4789+ length = index->index;
4790+ *next_block = index->start_block + sblk->directory_table_start;
4791+ }
4792+
4793+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4794+ kfree(str);
4795+failure:
4796+ return length;
4797+}
4798+
4799+
4800+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
4801+{
4802+ struct inode *i = file->f_dentry->d_inode;
4803+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4804+ struct squashfs_super_block *sblk = &msblk->sblk;
4805+ long long next_block = SQUASHFS_I(i)->start_block +
4806+ sblk->directory_table_start;
4807+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4808+ dir_count;
4809+ struct squashfs_dir_header_2 dirh;
4810+ struct squashfs_dir_entry_2 *dire;
4811+
4812+ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
4813+
4814+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4815+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4816+ ERROR("Failed to allocate squashfs_dir_entry\n");
4817+ goto finish;
4818+ }
4819+
4820+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
4821+ SQUASHFS_I(i)->u.s2.directory_index_start,
4822+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4823+ SQUASHFS_I(i)->u.s2.directory_index_count,
4824+ file->f_pos);
4825+
4826+ while (length < i_size_read(i)) {
4827+ /* read directory header */
4828+ if (msblk->swap) {
4829+ struct squashfs_dir_header_2 sdirh;
4830+
4831+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4832+ next_block, next_offset, sizeof(sdirh),
4833+ &next_block, &next_offset))
4834+ goto failed_read;
4835+
4836+ length += sizeof(sdirh);
4837+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4838+ } else {
4839+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4840+ next_block, next_offset, sizeof(dirh),
4841+ &next_block, &next_offset))
4842+ goto failed_read;
4843+
4844+ length += sizeof(dirh);
4845+ }
4846+
4847+ dir_count = dirh.count + 1;
4848+ while (dir_count--) {
4849+ if (msblk->swap) {
4850+ struct squashfs_dir_entry_2 sdire;
4851+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4852+ &sdire, next_block, next_offset,
4853+ sizeof(sdire), &next_block,
4854+ &next_offset))
4855+ goto failed_read;
4856+
4857+ length += sizeof(sdire);
4858+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4859+ } else {
4860+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4861+ dire, next_block, next_offset,
4862+ sizeof(*dire), &next_block,
4863+ &next_offset))
4864+ goto failed_read;
4865+
4866+ length += sizeof(*dire);
4867+ }
4868+
4869+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4870+ next_block, next_offset,
4871+ dire->size + 1, &next_block,
4872+ &next_offset))
4873+ goto failed_read;
4874+
4875+ length += dire->size + 1;
4876+
4877+ if (file->f_pos >= length)
4878+ continue;
4879+
4880+ dire->name[dire->size + 1] = '\0';
4881+
4882+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
4883+ (unsigned int) dirent, dire->name,
4884+ dire->size + 1, (int) file->f_pos,
4885+ dirh.start_block, dire->offset,
4886+ squashfs_filetype_table[dire->type]);
4887+
4888+ if (filldir(dirent, dire->name, dire->size + 1,
4889+ file->f_pos, SQUASHFS_MK_VFS_INODE(
4890+ dirh.start_block, dire->offset),
4891+ squashfs_filetype_table[dire->type])
4892+ < 0) {
4893+ TRACE("Filldir returned less than 0\n");
4894+ goto finish;
4895+ }
4896+ file->f_pos = length;
4897+ }
4898+ }
4899+
4900+finish:
4901+ kfree(dire);
4902+ return 0;
4903+
4904+failed_read:
4905+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4906+ next_offset);
4907+ kfree(dire);
4908+ return 0;
4909+}
4910+
4911+
4912+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
4913+ struct nameidata *nd)
4914+{
4915+ const unsigned char *name = dentry->d_name.name;
4916+ int len = dentry->d_name.len;
4917+ struct inode *inode = NULL;
4918+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4919+ struct squashfs_super_block *sblk = &msblk->sblk;
4920+ long long next_block = SQUASHFS_I(i)->start_block +
4921+ sblk->directory_table_start;
4922+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4923+ dir_count;
4924+ struct squashfs_dir_header_2 dirh;
4925+ struct squashfs_dir_entry_2 *dire;
4926+ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
4927+
4928+ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset);
4929+
4930+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4931+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4932+ ERROR("Failed to allocate squashfs_dir_entry\n");
4933+ goto exit_loop;
4934+ }
4935+
4936+ if (len > SQUASHFS_NAME_LEN)
4937+ goto exit_loop;
4938+
4939+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4940+ SQUASHFS_I(i)->u.s2.directory_index_start,
4941+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4942+ SQUASHFS_I(i)->u.s2.directory_index_count, name,
4943+ len);
4944+
4945+ while (length < i_size_read(i)) {
4946+ /* read directory header */
4947+ if (msblk->swap) {
4948+ struct squashfs_dir_header_2 sdirh;
4949+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4950+ next_block, next_offset, sizeof(sdirh),
4951+ &next_block, &next_offset))
4952+ goto failed_read;
4953+
4954+ length += sizeof(sdirh);
4955+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4956+ } else {
4957+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4958+ next_block, next_offset, sizeof(dirh),
4959+ &next_block, &next_offset))
4960+ goto failed_read;
4961+
4962+ length += sizeof(dirh);
4963+ }
4964+
4965+ dir_count = dirh.count + 1;
4966+ while (dir_count--) {
4967+ if (msblk->swap) {
4968+ struct squashfs_dir_entry_2 sdire;
4969+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4970+ &sdire, next_block,next_offset,
4971+ sizeof(sdire), &next_block,
4972+ &next_offset))
4973+ goto failed_read;
4974+
4975+ length += sizeof(sdire);
4976+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4977+ } else {
4978+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4979+ dire, next_block,next_offset,
4980+ sizeof(*dire), &next_block,
4981+ &next_offset))
4982+ goto failed_read;
4983+
4984+ length += sizeof(*dire);
4985+ }
4986+
4987+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4988+ next_block, next_offset, dire->size + 1,
4989+ &next_block, &next_offset))
4990+ goto failed_read;
4991+
4992+ length += dire->size + 1;
4993+
4994+ if (sorted && name[0] < dire->name[0])
4995+ goto exit_loop;
4996+
4997+ if ((len == dire->size + 1) && !strncmp(name,
4998+ dire->name, len)) {
4999+ squashfs_inode_t ino =
5000+ SQUASHFS_MKINODE(dirh.start_block,
5001+ dire->offset);
5002+ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block,
5003+ dire->offset);
5004+
5005+ TRACE("calling squashfs_iget for directory "
5006+ "entry %s, inode %x:%x, %lld\n", name,
5007+ dirh.start_block, dire->offset, ino);
5008+
5009+ inode = squashfs_iget(i->i_sb, ino, inode_number);
5010+
5011+ goto exit_loop;
5012+ }
5013+ }
5014+ }
5015+
5016+exit_loop:
5017+ kfree(dire);
5018+ d_add(dentry, inode);
5019+ return ERR_PTR(0);
5020+
5021+failed_read:
5022+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
5023+ next_offset);
5024+ goto exit_loop;
5025+}
5026+
5027+
5028+int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
5029+{
5030+ struct squashfs_super_block *sblk = &msblk->sblk;
5031+
5032+ msblk->read_inode = squashfs_read_inode_2;
5033+ msblk->read_fragment_index_table = read_fragment_index_table_2;
5034+
5035+ sblk->bytes_used = sblk->bytes_used_2;
5036+ sblk->uid_start = sblk->uid_start_2;
5037+ sblk->guid_start = sblk->guid_start_2;
5038+ sblk->inode_table_start = sblk->inode_table_start_2;
5039+ sblk->directory_table_start = sblk->directory_table_start_2;
5040+ sblk->fragment_table_start = sblk->fragment_table_start_2;
5041+
5042+ return 1;
5043+}
5044diff -uNr a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
5045--- a/fs/squashfs/squashfs.h 1969-12-31 16:00:00.000000000 -0800
5046+++ b/fs/squashfs/squashfs.h 2008-08-13 16:14:50.000000000 -0700
5047@@ -0,0 +1,122 @@
5048+/*
5049+ * Squashfs - a compressed read only filesystem for Linux
5050+ *
5051+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5052+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5053+ *
5054+ * This program is free software; you can redistribute it and/or
5055+ * modify it under the terms of the GNU General Public License
5056+ * as published by the Free Software Foundation; either version 2,
5057+ * or (at your option) any later version.
5058+ *
5059+ * This program is distributed in the hope that it will be useful,
5060+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5061+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5062+ * GNU General Public License for more details.
5063+ *
5064+ * You should have received a copy of the GNU General Public License
5065+ * along with this program; if not, write to the Free Software
5066+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5067+ *
5068+ * squashfs.h
5069+ */
5070+
5071+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5072+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5073+#endif
5074+
5075+#ifdef SQUASHFS_TRACE
5076+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
5077+#else
5078+#define TRACE(s, args...) {}
5079+#endif
5080+
5081+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args)
5082+
5083+#define SERROR(s, args...) do { \
5084+ if (!silent) \
5085+ printk(KERN_ERR "SQUASHFS error: "s, ## args);\
5086+ } while(0)
5087+
5088+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args)
5089+
5090+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
5091+{
5092+ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
5093+}
5094+
5095+/* block.c */
5096+extern unsigned int squashfs_read_data(struct super_block *, char *,
5097+ long long, unsigned int, long long *, int);
5098+extern int squashfs_get_cached_block(struct super_block *, void *,
5099+ long long, unsigned int, int, long long *, unsigned int *);
5100+
5101+/* cache.c */
5102+extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *,
5103+ struct squashfs_cache *, long long, int);
5104+extern void squashfs_cache_put(struct squashfs_cache *,
5105+ struct squashfs_cache_entry *);
5106+extern void squashfs_cache_delete(struct squashfs_cache *);
5107+extern struct squashfs_cache *squashfs_cache_init(char *, int, int, int);
5108+
5109+/* export.c */
5110+extern int read_inode_lookup_table(struct super_block *);
5111+
5112+/* file.c */
5113+extern long long read_blocklist(struct inode *, int, int, char *,
5114+ unsigned short **, unsigned int *);
5115+
5116+/* fragment.c */
5117+extern int get_fragment_location(struct super_block *, unsigned int,
5118+ long long *, unsigned int *);
5119+extern void release_cached_fragment(struct squashfs_sb_info *,
5120+ struct squashfs_cache_entry *);
5121+extern struct squashfs_cache_entry *get_cached_fragment(struct super_block *,
5122+ long long, int);
5123+extern int read_fragment_index_table(struct super_block *);
5124+
5125+/* id.c */
5126+extern int get_id(struct super_block *, unsigned int, unsigned int *);
5127+extern int read_id_index_table(struct super_block *);
5128+
5129+/* inode.c */
5130+extern struct inode *squashfs_iget(struct super_block *, squashfs_inode_t,
5131+ unsigned int);
5132+extern int squashfs_read_inode(struct inode *, squashfs_inode_t);
5133+
5134+/*
5135+ * Inodes and files operations
5136+ */
5137+
5138+/* dir.c */
5139+extern const struct file_operations squashfs_dir_ops;
5140+
5141+/* export.c */
5142+extern const struct export_operations squashfs_export_ops;
5143+
5144+/* file.c */
5145+extern const struct address_space_operations squashfs_aops;
5146+
5147+/* namei.c */
5148+extern const struct inode_operations squashfs_dir_inode_ops;
5149+
5150+/* symlink.c */
5151+extern const struct address_space_operations squashfs_symlink_aops;
5152+
5153+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5154+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
5155+#else
5156+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
5157+{
5158+ return 0;
5159+}
5160+#endif
5161+
5162+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5163+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
5164+#else
5165+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
5166+{
5167+ return 0;
5168+}
5169+#endif
5170diff -uNr a/fs/squashfs/super.c b/fs/squashfs/super.c
5171--- a/fs/squashfs/super.c 1969-12-31 16:00:00.000000000 -0800
5172+++ b/fs/squashfs/super.c 2008-08-13 16:14:50.000000000 -0700
5173@@ -0,0 +1,381 @@
5174+/*
5175+ * Squashfs - a compressed read only filesystem for Linux
5176+ *
5177+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5178+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5179+ *
5180+ * This program is free software; you can redistribute it and/or
5181+ * modify it under the terms of the GNU General Public License
5182+ * as published by the Free Software Foundation; either version 2,
5183+ * or (at your option) any later version.
5184+ *
5185+ * This program is distributed in the hope that it will be useful,
5186+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5187+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5188+ * GNU General Public License for more details.
5189+ *
5190+ * You should have received a copy of the GNU General Public License
5191+ * along with this program; if not, write to the Free Software
5192+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5193+ *
5194+ * super.c
5195+ */
5196+
5197+#include <linux/squashfs_fs.h>
5198+#include <linux/module.h>
5199+#include <linux/zlib.h>
5200+#include <linux/fs.h>
5201+#include <linux/squashfs_fs_sb.h>
5202+#include <linux/squashfs_fs_i.h>
5203+#include <linux/buffer_head.h>
5204+#include <linux/vfs.h>
5205+#include <linux/vmalloc.h>
5206+#include <linux/spinlock.h>
5207+#include <linux/smp_lock.h>
5208+#include <linux/exportfs.h>
5209+
5210+#include "squashfs.h"
5211+
5212+static struct file_system_type squashfs_fs_type;
5213+static struct super_operations squashfs_super_ops;
5214+
5215+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
5216+{
5217+ struct squashfs_super_block *sblk = &msblk->sblk;
5218+
5219+ msblk->read_inode = squashfs_read_inode;
5220+ msblk->read_blocklist = read_blocklist;
5221+ msblk->read_fragment_index_table = read_fragment_index_table;
5222+
5223+ if (sblk->s_major == 1) {
5224+ if (!squashfs_1_0_supported(msblk)) {
5225+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
5226+ "are unsupported\n");
5227+ SERROR("Please recompile with Squashfs 1.0 support enabled\n");
5228+ return 0;
5229+ }
5230+ } else if (sblk->s_major == 2) {
5231+ if (!squashfs_2_0_supported(msblk)) {
5232+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
5233+ "are unsupported\n");
5234+ SERROR("Please recompile with Squashfs 2.0 support enabled\n");
5235+ return 0;
5236+ }
5237+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
5238+ SQUASHFS_MINOR) {
5239+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
5240+ "filesystem\n", sblk->s_major, sblk->s_minor);
5241+ SERROR("Please update your kernel\n");
5242+ return 0;
5243+ }
5244+
5245+ return 1;
5246+}
5247+
5248+
5249+static int squashfs_fill_super(struct super_block *s, void *data, int silent)
5250+{
5251+ struct squashfs_sb_info *msblk;
5252+ struct squashfs_super_block *sblk;
5253+ char b[BDEVNAME_SIZE];
5254+ struct inode *root;
5255+
5256+ TRACE("Entered squashfs_fill_superblock\n");
5257+
5258+ s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL);
5259+ if (s->s_fs_info == NULL) {
5260+ ERROR("Failed to allocate superblock\n");
5261+ goto failure;
5262+ }
5263+ msblk = s->s_fs_info;
5264+
5265+ msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize());
5266+ if (msblk->stream.workspace == NULL) {
5267+ ERROR("Failed to allocate zlib workspace\n");
5268+ goto failure;
5269+ }
5270+ sblk = &msblk->sblk;
5271+
5272+ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
5273+ msblk->devblksize_log2 = ffz(~msblk->devblksize);
5274+
5275+ mutex_init(&msblk->read_data_mutex);
5276+ mutex_init(&msblk->read_page_mutex);
5277+ mutex_init(&msblk->meta_index_mutex);
5278+
5279+ /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not
5280+ * beyond filesystem end. As we're using squashfs_read_data to read sblk here,
5281+ * first set sblk->bytes_used to a useful value */
5282+ sblk->bytes_used = sizeof(struct squashfs_super_block);
5283+ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
5284+ sizeof(struct squashfs_super_block) |
5285+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) {
5286+ SERROR("unable to read superblock\n");
5287+ goto failed_mount;
5288+ }
5289+
5290+ /* Check it is a SQUASHFS superblock */
5291+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
5292+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
5293+ struct squashfs_super_block ssblk;
5294+
5295+ WARNING("Mounting a different endian SQUASHFS filesystem on %s\n",
5296+ bdevname(s->s_bdev, b));
5297+
5298+ //SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
5299+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
5300+ msblk->swap = 1;
5301+ } else {
5302+ SERROR("Can't find a SQUASHFS superblock on %s\n",
5303+ bdevname(s->s_bdev, b));
5304+ goto failed_mount;
5305+ }
5306+ }
5307+
5308+ /* Check the MAJOR & MINOR versions */
5309+ if(!supported_squashfs_filesystem(msblk, silent))
5310+ goto failed_mount;
5311+
5312+ /* Check the filesystem does not extend beyond the end of the
5313+ block device */
5314+ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
5315+ goto failed_mount;
5316+
5317+ /* Check the root inode for sanity */
5318+ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
5319+ goto failed_mount;
5320+
5321+ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
5322+ TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sblk->flags)
5323+ ? "un" : "");
5324+ TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
5325+ ? "un" : "");
5326+ TRACE("Check data is %spresent in the filesystem\n",
5327+ SQUASHFS_CHECK_DATA(sblk->flags) ? "" : "not ");
5328+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
5329+ TRACE("Block size %d\n", sblk->block_size);
5330+ TRACE("Number of inodes %d\n", sblk->inodes);
5331+ if (sblk->s_major > 1)
5332+ TRACE("Number of fragments %d\n", sblk->fragments);
5333+ TRACE("Number of ids %d\n", sblk->no_ids);
5334+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
5335+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
5336+ if (sblk->s_major > 1)
5337+ TRACE("sblk->fragment_table_start %llx\n", sblk->fragment_table_start);
5338+ TRACE("sblk->id_table_start %llx\n", sblk->id_table_start);
5339+
5340+ s->s_maxbytes = MAX_LFS_FILESIZE;
5341+ s->s_flags |= MS_RDONLY;
5342+ s->s_op = &squashfs_super_ops;
5343+
5344+ msblk->block_cache = squashfs_cache_init("metadata", SQUASHFS_CACHED_BLKS,
5345+ SQUASHFS_METADATA_SIZE, 0);
5346+ if (msblk->block_cache == NULL)
5347+ goto failed_mount;
5348+
5349+ /* Allocate read_page block */
5350+ msblk->read_page = vmalloc(sblk->block_size);
5351+ if (msblk->read_page == NULL) {
5352+ ERROR("Failed to allocate read_page block\n");
5353+ goto failed_mount;
5354+ }
5355+
5356+ /* Allocate and read id index table */
5357+ if (read_id_index_table(s) == 0)
5358+ goto failed_mount;
5359+
5360+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
5361+ goto allocate_root;
5362+
5363+ msblk->fragment_cache = squashfs_cache_init("fragment",
5364+ SQUASHFS_CACHED_FRAGMENTS, sblk->block_size, 1);
5365+ if (msblk->fragment_cache == NULL)
5366+ goto failed_mount;
5367+
5368+ /* Allocate and read fragment index table */
5369+ if (msblk->read_fragment_index_table(s) == 0)
5370+ goto failed_mount;
5371+
5372+ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
5373+ goto allocate_root;
5374+
5375+ /* Allocate and read inode lookup table */
5376+ if (read_inode_lookup_table(s) == 0)
5377+ goto failed_mount;
5378+
5379+ s->s_export_op = &squashfs_export_ops;
5380+
5381+allocate_root:
5382+ root = new_inode(s);
5383+ if ((msblk->read_inode)(root, sblk->root_inode) == 0)
5384+ goto failed_mount;
5385+ insert_inode_hash(root);
5386+
5387+ s->s_root = d_alloc_root(root);
5388+ if (s->s_root == NULL) {
5389+ ERROR("Root inode create failed\n");
5390+ iput(root);
5391+ goto failed_mount;
5392+ }
5393+
5394+ TRACE("Leaving squashfs_fill_super\n");
5395+ return 0;
5396+
5397+failed_mount:
5398+ kfree(msblk->inode_lookup_table);
5399+ kfree(msblk->fragment_index);
5400+ squashfs_cache_delete(msblk->fragment_cache);
5401+ kfree(msblk->id_table);
5402+ vfree(msblk->read_page);
5403+ squashfs_cache_delete(msblk->block_cache);
5404+ kfree(msblk->fragment_index_2);
5405+ vfree(msblk->stream.workspace);
5406+ kfree(s->s_fs_info);
5407+ s->s_fs_info = NULL;
5408+ return -EINVAL;
5409+
5410+failure:
5411+ return -ENOMEM;
5412+}
5413+
5414+
5415+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
5416+{
5417+ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
5418+ struct squashfs_super_block *sblk = &msblk->sblk;
5419+
5420+ TRACE("Entered squashfs_statfs\n");
5421+
5422+ buf->f_type = SQUASHFS_MAGIC;
5423+ buf->f_bsize = sblk->block_size;
5424+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
5425+ buf->f_bfree = buf->f_bavail = 0;
5426+ buf->f_files = sblk->inodes;
5427+ buf->f_ffree = 0;
5428+ buf->f_namelen = SQUASHFS_NAME_LEN;
5429+
5430+ return 0;
5431+}
5432+
5433+
5434+static int squashfs_remount(struct super_block *s, int *flags, char *data)
5435+{
5436+ *flags |= MS_RDONLY;
5437+ return 0;
5438+}
5439+
5440+
5441+static void squashfs_put_super(struct super_block *s)
5442+{
5443+ if (s->s_fs_info) {
5444+ struct squashfs_sb_info *sbi = s->s_fs_info;
5445+ squashfs_cache_delete(sbi->block_cache);
5446+ squashfs_cache_delete(sbi->fragment_cache);
5447+ vfree(sbi->read_page);
5448+ kfree(sbi->id_table);
5449+ kfree(sbi->fragment_index);
5450+ kfree(sbi->fragment_index_2);
5451+ kfree(sbi->meta_index);
5452+ vfree(sbi->stream.workspace);
5453+ kfree(s->s_fs_info);
5454+ s->s_fs_info = NULL;
5455+ }
5456+}
5457+
5458+
5459+static int squashfs_get_sb(struct file_system_type *fs_type, int flags,
5460+ const char *dev_name, void *data, struct vfsmount *mnt)
5461+{
5462+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super,
5463+ mnt);
5464+}
5465+
5466+
5467+static struct kmem_cache * squashfs_inode_cachep;
5468+
5469+
5470+static void init_once(void *foo)
5471+{
5472+ struct squashfs_inode_info *ei = foo;
5473+
5474+ inode_init_once(&ei->vfs_inode);
5475+}
5476+
5477+
5478+static int __init init_inodecache(void)
5479+{
5480+ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
5481+ sizeof(struct squashfs_inode_info), 0,
5482+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once);
5483+ if (squashfs_inode_cachep == NULL)
5484+ return -ENOMEM;
5485+ return 0;
5486+}
5487+
5488+
5489+static void destroy_inodecache(void)
5490+{
5491+ kmem_cache_destroy(squashfs_inode_cachep);
5492+}
5493+
5494+
5495+static int __init init_squashfs_fs(void)
5496+{
5497+ int err = init_inodecache();
5498+ if (err)
5499+ goto out;
5500+
5501+ printk(KERN_INFO "squashfs: version 4.0-CVS (2008/07/27) "
5502+ "Phillip Lougher\n");
5503+
5504+ err = register_filesystem(&squashfs_fs_type);
5505+ if (err)
5506+ destroy_inodecache();
5507+
5508+out:
5509+ return err;
5510+}
5511+
5512+
5513+static void __exit exit_squashfs_fs(void)
5514+{
5515+ unregister_filesystem(&squashfs_fs_type);
5516+ destroy_inodecache();
5517+}
5518+
5519+
5520+static struct inode *squashfs_alloc_inode(struct super_block *sb)
5521+{
5522+ struct squashfs_inode_info *ei;
5523+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
5524+ return ei ? &ei->vfs_inode : NULL;
5525+}
5526+
5527+
5528+static void squashfs_destroy_inode(struct inode *inode)
5529+{
5530+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
5531+}
5532+
5533+
5534+static struct file_system_type squashfs_fs_type = {
5535+ .owner = THIS_MODULE,
5536+ .name = "squashfs",
5537+ .get_sb = squashfs_get_sb,
5538+ .kill_sb = kill_block_super,
5539+ .fs_flags = FS_REQUIRES_DEV
5540+};
5541+
5542+static struct super_operations squashfs_super_ops = {
5543+ .alloc_inode = squashfs_alloc_inode,
5544+ .destroy_inode = squashfs_destroy_inode,
5545+ .statfs = squashfs_statfs,
5546+ .put_super = squashfs_put_super,
5547+ .remount_fs = squashfs_remount
5548+};
5549+
5550+module_init(init_squashfs_fs);
5551+module_exit(exit_squashfs_fs);
5552+MODULE_DESCRIPTION("squashfs 4.0-CVS, a compressed read-only filesystem");
5553+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
5554+MODULE_LICENSE("GPL");
5555diff -uNr a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
5556--- a/fs/squashfs/symlink.c 1969-12-31 16:00:00.000000000 -0800
5557+++ b/fs/squashfs/symlink.c 2008-08-13 16:14:50.000000000 -0700
5558@@ -0,0 +1,85 @@
5559+/*
5560+ * Squashfs - a compressed read only filesystem for Linux
5561+ *
5562+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5563+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5564+ *
5565+ * This program is free software; you can redistribute it and/or
5566+ * modify it under the terms of the GNU General Public License
5567+ * as published by the Free Software Foundation; either version 2,
5568+ * or (at your option) any later version.
5569+ *
5570+ * This program is distributed in the hope that it will be useful,
5571+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5572+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5573+ * GNU General Public License for more details.
5574+ *
5575+ * You should have received a copy of the GNU General Public License
5576+ * along with this program; if not, write to the Free Software
5577+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5578+ *
5579+ * symlink.c
5580+ */
5581+
5582+#include <linux/fs.h>
5583+#include <linux/vfs.h>
5584+#include <linux/zlib.h>
5585+#include <linux/buffer_head.h>
5586+#include <linux/squashfs_fs.h>
5587+#include <linux/squashfs_fs_sb.h>
5588+#include <linux/squashfs_fs_i.h>
5589+
5590+#include "squashfs.h"
5591+
5592+static int squashfs_symlink_readpage(struct file *file, struct page *page)
5593+{
5594+ struct inode *inode = page->mapping->host;
5595+ int index = page->index << PAGE_CACHE_SHIFT;
5596+ long long block = SQUASHFS_I(inode)->start_block;
5597+ int offset = SQUASHFS_I(inode)->offset;
5598+ void *pageaddr = kmap(page);
5599+ int length, bytes, avail_bytes;
5600+
5601+ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
5602+ "%llx, offset %x\n", page->index,
5603+ SQUASHFS_I(inode)->start_block,
5604+ SQUASHFS_I(inode)->offset);
5605+
5606+ for (length = 0; length < index; length += bytes) {
5607+ bytes = squashfs_get_cached_block(inode->i_sb, NULL, block,
5608+ offset, PAGE_CACHE_SIZE, &block, &offset);
5609+ if (bytes == 0) {
5610+ ERROR("Unable to read symbolic link [%llx:%x]\n",
5611+ block, offset);
5612+ goto skip_read;
5613+ }
5614+ }
5615+
5616+ if (length != index) {
5617+ ERROR("(squashfs_symlink_readpage) length != index\n");
5618+ bytes = 0;
5619+ goto skip_read;
5620+ }
5621+
5622+ avail_bytes = min_t(int, i_size_read(inode) - length, PAGE_CACHE_SIZE);
5623+
5624+ bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset,
5625+ avail_bytes, &block, &offset);
5626+ if (bytes == 0)
5627+ ERROR("Unable to read symbolic link [%llx:%x]\n", block,
5628+ offset);
5629+
5630+skip_read:
5631+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
5632+ kunmap(page);
5633+ flush_dcache_page(page);
5634+ SetPageUptodate(page);
5635+ unlock_page(page);
5636+
5637+ return 0;
5638+}
5639+
5640+
5641+const struct address_space_operations squashfs_symlink_aops = {
5642+ .readpage = squashfs_symlink_readpage
5643+};
5644diff -uNr a/include/linux/squashfs_fs.h b/include/linux/squashfs_fs.h
5645--- a/include/linux/squashfs_fs.h 1969-12-31 16:00:00.000000000 -0800
5646+++ b/include/linux/squashfs_fs.h 2008-08-13 16:16:05.000000000 -0700
5647@@ -0,0 +1,949 @@
5648+#ifndef SQUASHFS_FS
5649+#define SQUASHFS_FS
5650+/*
5651+ * Squashfs
5652+ *
5653+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5654+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5655+ *
5656+ * This program is free software; you can redistribute it and/or
5657+ * modify it under the terms of the GNU General Public License
5658+ * as published by the Free Software Foundation; either version 2,
5659+ * or (at your option) any later version.
5660+ *
5661+ * This program is distributed in the hope that it will be useful,
5662+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5663+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5664+ * GNU General Public License for more details.
5665+ *
5666+ * You should have received a copy of the GNU General Public License
5667+ * along with this program; if not, write to the Free Software
5668+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5669+ *
5670+ * squashfs_fs.h
5671+ */
5672+
5673+#if 0
5674+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5675+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
5676+#endif
5677+#endif
5678+
5679+#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
5680+#define SQUASHFS_MAJOR 4
5681+#define SQUASHFS_MINOR 0
5682+#define SQUASHFS_MAGIC 0x73717368
5683+#define SQUASHFS_MAGIC_SWAP 0x68737173
5684+#define SQUASHFS_START 0
5685+
5686+/* size of metadata (inode and directory) blocks */
5687+#define SQUASHFS_METADATA_SIZE 8192
5688+#define SQUASHFS_METADATA_LOG 13
5689+
5690+/* default size of data blocks */
5691+#define SQUASHFS_FILE_SIZE 131072
5692+#define SQUASHFS_FILE_LOG 17
5693+
5694+#define SQUASHFS_FILE_MAX_SIZE 1048576
5695+
5696+/* Max number of uids and gids */
5697+#define SQUASHFS_IDS 65536
5698+
5699+/* Max length of filename (not 255) */
5700+#define SQUASHFS_NAME_LEN 256
5701+
5702+#define SQUASHFS_INVALID ((long long) 0xffffffffffff)
5703+#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
5704+#define SQUASHFS_INVALID_BLK ((long long) -1)
5705+#define SQUASHFS_USED_BLK ((long long) -2)
5706+
5707+/* Filesystem flags */
5708+#define SQUASHFS_NOI 0
5709+#define SQUASHFS_NOD 1
5710+#define SQUASHFS_CHECK 2
5711+#define SQUASHFS_NOF 3
5712+#define SQUASHFS_NO_FRAG 4
5713+#define SQUASHFS_ALWAYS_FRAG 5
5714+#define SQUASHFS_DUPLICATE 6
5715+#define SQUASHFS_EXPORT 7
5716+
5717+#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
5718+
5719+#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
5720+ SQUASHFS_NOI)
5721+
5722+#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
5723+ SQUASHFS_NOD)
5724+
5725+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5726+ SQUASHFS_NOF)
5727+
5728+#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5729+ SQUASHFS_NO_FRAG)
5730+
5731+#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5732+ SQUASHFS_ALWAYS_FRAG)
5733+
5734+#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
5735+ SQUASHFS_DUPLICATE)
5736+
5737+#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
5738+ SQUASHFS_EXPORT)
5739+
5740+#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
5741+ SQUASHFS_CHECK)
5742+
5743+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
5744+ duplicate_checking, exportable) (noi | (nod << 1) | (check_data << 2) \
5745+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
5746+ (duplicate_checking << 6) | (exportable << 7))
5747+
5748+/* Max number of types and file types */
5749+#define SQUASHFS_DIR_TYPE 1
5750+#define SQUASHFS_FILE_TYPE 2
5751+#define SQUASHFS_SYMLINK_TYPE 3
5752+#define SQUASHFS_BLKDEV_TYPE 4
5753+#define SQUASHFS_CHRDEV_TYPE 5
5754+#define SQUASHFS_FIFO_TYPE 6
5755+#define SQUASHFS_SOCKET_TYPE 7
5756+#define SQUASHFS_LDIR_TYPE 8
5757+#define SQUASHFS_LREG_TYPE 9
5758+
5759+/* 1.0 filesystem type definitions */
5760+#define SQUASHFS_TYPES 5
5761+#define SQUASHFS_IPC_TYPE 0
5762+
5763+/* Flag whether block is compressed or uncompressed, bit is set if block is
5764+ * uncompressed */
5765+#define SQUASHFS_COMPRESSED_BIT (1 << 15)
5766+
5767+#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
5768+ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
5769+
5770+#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
5771+
5772+#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
5773+
5774+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \
5775+ ~SQUASHFS_COMPRESSED_BIT_BLOCK)
5776+
5777+#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
5778+
5779+/*
5780+ * Inode number ops. Inodes consist of a compressed block number, and an
5781+ * uncompressed offset within that block
5782+ */
5783+#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
5784+
5785+#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
5786+
5787+#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
5788+ << 16) + (B)))
5789+
5790+/* Compute 32 bit VFS inode number from squashfs inode number */
5791+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
5792+ ((b) >> 2) + 1))
5793+/* XXX */
5794+
5795+/* Translate between VFS mode and squashfs mode */
5796+#define SQUASHFS_MODE(a) ((a) & 0xfff)
5797+
5798+/* fragment and fragment table defines */
5799+#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry))
5800+
5801+#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
5802+ SQUASHFS_METADATA_SIZE)
5803+
5804+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
5805+ SQUASHFS_METADATA_SIZE)
5806+
5807+#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
5808+ SQUASHFS_METADATA_SIZE - 1) / \
5809+ SQUASHFS_METADATA_SIZE)
5810+
5811+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
5812+ sizeof(long long))
5813+
5814+/* inode lookup table defines */
5815+#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t))
5816+
5817+#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
5818+ SQUASHFS_METADATA_SIZE)
5819+
5820+#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
5821+ SQUASHFS_METADATA_SIZE)
5822+
5823+#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
5824+ SQUASHFS_METADATA_SIZE - 1) / \
5825+ SQUASHFS_METADATA_SIZE)
5826+
5827+#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
5828+ sizeof(long long))
5829+
5830+/* uid lookup table defines */
5831+#define SQUASHFS_ID_BYTES(A) ((A) * sizeof(unsigned int))
5832+
5833+#define SQUASHFS_ID_BLOCK(A) (SQUASHFS_ID_BYTES(A) / \
5834+ SQUASHFS_METADATA_SIZE)
5835+
5836+#define SQUASHFS_ID_BLOCK_OFFSET(A) (SQUASHFS_ID_BYTES(A) % \
5837+ SQUASHFS_METADATA_SIZE)
5838+
5839+#define SQUASHFS_ID_BLOCKS(A) ((SQUASHFS_ID_BYTES(A) + \
5840+ SQUASHFS_METADATA_SIZE - 1) / \
5841+ SQUASHFS_METADATA_SIZE)
5842+
5843+#define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\
5844+ sizeof(long long))
5845+
5846+/* cached data constants for filesystem */
5847+#define SQUASHFS_CACHED_BLKS 8
5848+
5849+#define SQUASHFS_MAX_FILE_SIZE_LOG 64
5850+
5851+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
5852+ (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
5853+
5854+#define SQUASHFS_MARKER_BYTE 0xff
5855+
5856+/* meta index cache */
5857+#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
5858+#define SQUASHFS_META_ENTRIES 31
5859+#define SQUASHFS_META_NUMBER 8
5860+#define SQUASHFS_SLOTS 4
5861+
5862+struct meta_entry {
5863+ long long data_block;
5864+ unsigned int index_block;
5865+ unsigned short offset;
5866+ unsigned short pad;
5867+};
5868+
5869+struct meta_index {
5870+ unsigned int inode_number;
5871+ unsigned int offset;
5872+ unsigned short entries;
5873+ unsigned short skip;
5874+ unsigned short locked;
5875+ unsigned short pad;
5876+ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
5877+};
5878+
5879+
5880+/*
5881+ * definitions for structures on disk
5882+ */
5883+
5884+typedef long long squashfs_block_t;
5885+typedef long long squashfs_inode_t;
5886+
5887+#define COMPRESSION_ZLIB 1
5888+
5889+struct squashfs_super_block {
5890+ unsigned int s_magic;
5891+ unsigned int inodes;
5892+ unsigned int mkfs_time /* time of filesystem creation */;
5893+ unsigned int block_size;
5894+ unsigned int fragments;
5895+ unsigned short compression;
5896+ unsigned short block_log;
5897+ unsigned short flags;
5898+ unsigned short no_ids;
5899+ unsigned short s_major;
5900+ unsigned short s_minor;
5901+ squashfs_inode_t root_inode;
5902+ long long bytes_used;
5903+ long long id_table_start;
5904+ long long xattr_table_start;
5905+ long long inode_table_start;
5906+ long long directory_table_start;
5907+ long long fragment_table_start;
5908+ long long lookup_table_start;
5909+};
5910+
5911+struct squashfs_dir_index {
5912+ unsigned int index;
5913+ unsigned int start_block;
5914+ unsigned int size;
5915+ unsigned char name[0];
5916+};
5917+
5918+#define SQUASHFS_BASE_INODE_HEADER \
5919+ unsigned short inode_type; \
5920+ unsigned short mode; \
5921+ unsigned short uid; \
5922+ unsigned short guid; \
5923+ unsigned int mtime; \
5924+ unsigned int inode_number;
5925+
5926+struct squashfs_base_inode_header {
5927+ SQUASHFS_BASE_INODE_HEADER;
5928+};
5929+
5930+struct squashfs_ipc_inode_header {
5931+ SQUASHFS_BASE_INODE_HEADER;
5932+ unsigned int nlink;
5933+};
5934+
5935+struct squashfs_dev_inode_header {
5936+ SQUASHFS_BASE_INODE_HEADER;
5937+ unsigned int nlink;
5938+ unsigned int rdev;
5939+};
5940+
5941+struct squashfs_symlink_inode_header {
5942+ SQUASHFS_BASE_INODE_HEADER;
5943+ unsigned int nlink;
5944+ unsigned int symlink_size;
5945+ char symlink[0];
5946+};
5947+
5948+struct squashfs_reg_inode_header {
5949+ SQUASHFS_BASE_INODE_HEADER;
5950+ unsigned int start_block;
5951+ unsigned int fragment;
5952+ unsigned int offset;
5953+ unsigned int file_size;
5954+ unsigned short block_list[0];
5955+};
5956+
5957+struct squashfs_lreg_inode_header {
5958+ SQUASHFS_BASE_INODE_HEADER;
5959+ squashfs_block_t start_block;
5960+ long long file_size;
5961+ long long sparse;
5962+ unsigned int nlink;
5963+ unsigned int fragment;
5964+ unsigned int offset;
5965+ unsigned int xattr;
5966+ unsigned short block_list[0];
5967+};
5968+
5969+struct squashfs_dir_inode_header {
5970+ SQUASHFS_BASE_INODE_HEADER;
5971+ unsigned int start_block;
5972+ unsigned int nlink;
5973+ unsigned short file_size;
5974+ unsigned short offset;
5975+ unsigned int parent_inode;
5976+};
5977+
5978+struct squashfs_ldir_inode_header {
5979+ SQUASHFS_BASE_INODE_HEADER;
5980+ unsigned int nlink;
5981+ unsigned int file_size;
5982+ unsigned int start_block;
5983+ unsigned int parent_inode;
5984+ unsigned short i_count;
5985+ unsigned short offset;
5986+ struct squashfs_dir_index index[0];
5987+};
5988+
5989+union squashfs_inode_header {
5990+ struct squashfs_base_inode_header base;
5991+ struct squashfs_dev_inode_header dev;
5992+ struct squashfs_symlink_inode_header symlink;
5993+ struct squashfs_reg_inode_header reg;
5994+ struct squashfs_lreg_inode_header lreg;
5995+ struct squashfs_dir_inode_header dir;
5996+ struct squashfs_ldir_inode_header ldir;
5997+ struct squashfs_ipc_inode_header ipc;
5998+};
5999+
6000+struct squashfs_dir_entry {
6001+ unsigned short offset;
6002+ short inode_number;
6003+ unsigned short type;
6004+ unsigned short size;
6005+ char name[0];
6006+};
6007+
6008+struct squashfs_dir_header {
6009+ unsigned int count;
6010+ unsigned int start_block;
6011+ unsigned int inode_number;
6012+};
6013+
6014+struct squashfs_fragment_entry {
6015+ long long start_block;
6016+ unsigned int size;
6017+ unsigned int unused;
6018+};
6019+
6020+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
6021+extern int squashfs_uncompress_init(void);
6022+extern int squashfs_uncompress_exit(void);
6023+
6024+/*
6025+ * macros to convert each packed bitfield structure from little endian to big
6026+ * endian and vice versa. These are needed when creating or using a filesystem
6027+ * on a machine with different byte ordering to the target architecture.
6028+ *
6029+ */
6030+
6031+#define SQUASHFS_SWAP_START \
6032+ int bits;\
6033+ int b_pos;\
6034+ unsigned long long val;\
6035+ unsigned char *s;\
6036+ unsigned char *d;
6037+
6038+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
6039+ SQUASHFS_SWAP_START\
6040+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
6041+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
6042+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
6043+ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
6044+ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
6045+ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
6046+ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
6047+ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
6048+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
6049+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
6050+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
6051+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
6052+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\
6053+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
6054+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
6055+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
6056+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
6057+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
6058+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
6059+ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
6060+ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
6061+ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
6062+ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
6063+ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
6064+ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
6065+ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
6066+ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\
6067+}
6068+
6069+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
6070+ SQUASHFS_MEMSET(s, d, n);\
6071+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6072+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6073+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
6074+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
6075+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
6076+ SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
6077+
6078+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
6079+ SQUASHFS_SWAP_START\
6080+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
6081+}
6082+
6083+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
6084+ SQUASHFS_SWAP_START\
6085+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6086+ sizeof(struct squashfs_ipc_inode_header))\
6087+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6088+}
6089+
6090+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
6091+ SQUASHFS_SWAP_START\
6092+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6093+ sizeof(struct squashfs_dev_inode_header)); \
6094+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6095+ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
6096+}
6097+
6098+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
6099+ SQUASHFS_SWAP_START\
6100+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6101+ sizeof(struct squashfs_symlink_inode_header));\
6102+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6103+ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
6104+}
6105+
6106+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
6107+ SQUASHFS_SWAP_START\
6108+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6109+ sizeof(struct squashfs_reg_inode_header));\
6110+ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
6111+ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
6112+ SQUASHFS_SWAP((s)->offset, d, 192, 32);\
6113+ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
6114+}
6115+
6116+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
6117+ SQUASHFS_SWAP_START\
6118+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6119+ sizeof(struct squashfs_lreg_inode_header));\
6120+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6121+ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
6122+ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
6123+ SQUASHFS_SWAP((s)->offset, d, 224, 32);\
6124+ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
6125+}
6126+
6127+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
6128+ SQUASHFS_SWAP_START\
6129+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6130+ sizeof(struct squashfs_dir_inode_header));\
6131+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6132+ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
6133+ SQUASHFS_SWAP((s)->offset, d, 147, 13);\
6134+ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
6135+ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
6136+}
6137+
6138+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
6139+ SQUASHFS_SWAP_START\
6140+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6141+ sizeof(struct squashfs_ldir_inode_header));\
6142+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6143+ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
6144+ SQUASHFS_SWAP((s)->offset, d, 155, 13);\
6145+ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
6146+ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
6147+ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
6148+}
6149+
6150+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
6151+ SQUASHFS_SWAP_START\
6152+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
6153+ SQUASHFS_SWAP((s)->index, d, 0, 32);\
6154+ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
6155+ SQUASHFS_SWAP((s)->size, d, 64, 8);\
6156+}
6157+
6158+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
6159+ SQUASHFS_SWAP_START\
6160+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
6161+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
6162+ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
6163+ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
6164+}
6165+
6166+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
6167+ SQUASHFS_SWAP_START\
6168+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
6169+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
6170+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
6171+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
6172+ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
6173+}
6174+
6175+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
6176+ SQUASHFS_SWAP_START\
6177+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
6178+ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
6179+ SQUASHFS_SWAP((s)->size, d, 64, 32);\
6180+}
6181+
6182+#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1)
6183+
6184+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
6185+ int entry;\
6186+ int bit_position;\
6187+ SQUASHFS_SWAP_START\
6188+ SQUASHFS_MEMSET(s, d, n * 2);\
6189+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6190+ 16)\
6191+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
6192+}
6193+
6194+#define SQUASHFS_SWAP_INTS(s, d, n) {\
6195+ int entry;\
6196+ int bit_position;\
6197+ SQUASHFS_SWAP_START\
6198+ SQUASHFS_MEMSET(s, d, n * 4);\
6199+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6200+ 32)\
6201+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
6202+}
6203+
6204+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
6205+ int entry;\
6206+ int bit_position;\
6207+ SQUASHFS_SWAP_START\
6208+ SQUASHFS_MEMSET(s, d, n * 8);\
6209+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6210+ 64)\
6211+ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
6212+}
6213+
6214+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
6215+ int entry;\
6216+ int bit_position;\
6217+ SQUASHFS_SWAP_START\
6218+ SQUASHFS_MEMSET(s, d, n * bits / 8);\
6219+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6220+ bits)\
6221+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
6222+}
6223+
6224+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6225+#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6226+#define SQUASHFS_SWAP_ID_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6227+
6228+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
6229+
6230+struct squashfs_base_inode_header_1 {
6231+ unsigned int inode_type:4;
6232+ unsigned int mode:12; /* protection */
6233+ unsigned int uid:4; /* index into uid table */
6234+ unsigned int guid:4; /* index into guid table */
6235+} __attribute__ ((packed));
6236+
6237+struct squashfs_ipc_inode_header_1 {
6238+ unsigned int inode_type:4;
6239+ unsigned int mode:12; /* protection */
6240+ unsigned int uid:4; /* index into uid table */
6241+ unsigned int guid:4; /* index into guid table */
6242+ unsigned int type:4;
6243+ unsigned int offset:4;
6244+} __attribute__ ((packed));
6245+
6246+struct squashfs_dev_inode_header_1 {
6247+ unsigned int inode_type:4;
6248+ unsigned int mode:12; /* protection */
6249+ unsigned int uid:4; /* index into uid table */
6250+ unsigned int guid:4; /* index into guid table */
6251+ unsigned short rdev;
6252+} __attribute__ ((packed));
6253+
6254+struct squashfs_symlink_inode_header_1 {
6255+ unsigned int inode_type:4;
6256+ unsigned int mode:12; /* protection */
6257+ unsigned int uid:4; /* index into uid table */
6258+ unsigned int guid:4; /* index into guid table */
6259+ unsigned short symlink_size;
6260+ char symlink[0];
6261+} __attribute__ ((packed));
6262+
6263+struct squashfs_reg_inode_header_1 {
6264+ unsigned int inode_type:4;
6265+ unsigned int mode:12; /* protection */
6266+ unsigned int uid:4; /* index into uid table */
6267+ unsigned int guid:4; /* index into guid table */
6268+ unsigned int mtime;
6269+ unsigned int start_block;
6270+ unsigned int file_size:32;
6271+ unsigned short block_list[0];
6272+} __attribute__ ((packed));
6273+
6274+struct squashfs_dir_inode_header_1 {
6275+ unsigned int inode_type:4;
6276+ unsigned int mode:12; /* protection */
6277+ unsigned int uid:4; /* index into uid table */
6278+ unsigned int guid:4; /* index into guid table */
6279+ unsigned int file_size:19;
6280+ unsigned int offset:13;
6281+ unsigned int mtime;
6282+ unsigned int start_block:24;
6283+} __attribute__ ((packed));
6284+
6285+union squashfs_inode_header_1 {
6286+ struct squashfs_base_inode_header_1 base;
6287+ struct squashfs_dev_inode_header_1 dev;
6288+ struct squashfs_symlink_inode_header_1 symlink;
6289+ struct squashfs_reg_inode_header_1 reg;
6290+ struct squashfs_dir_inode_header_1 dir;
6291+ struct squashfs_ipc_inode_header_1 ipc;
6292+};
6293+
6294+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
6295+ SQUASHFS_MEMSET(s, d, n);\
6296+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6297+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6298+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\
6299+ SQUASHFS_SWAP((s)->guid, d, 20, 4);
6300+
6301+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
6302+ SQUASHFS_SWAP_START\
6303+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
6304+}
6305+
6306+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
6307+ SQUASHFS_SWAP_START\
6308+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6309+ sizeof(struct squashfs_ipc_inode_header_1));\
6310+ SQUASHFS_SWAP((s)->type, d, 24, 4);\
6311+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\
6312+}
6313+
6314+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
6315+ SQUASHFS_SWAP_START\
6316+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6317+ sizeof(struct squashfs_dev_inode_header_1));\
6318+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
6319+}
6320+
6321+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
6322+ SQUASHFS_SWAP_START\
6323+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6324+ sizeof(struct squashfs_symlink_inode_header_1));\
6325+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
6326+}
6327+
6328+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
6329+ SQUASHFS_SWAP_START\
6330+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6331+ sizeof(struct squashfs_reg_inode_header_1));\
6332+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
6333+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
6334+ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
6335+}
6336+
6337+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
6338+ SQUASHFS_SWAP_START\
6339+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6340+ sizeof(struct squashfs_dir_inode_header_1));\
6341+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
6342+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\
6343+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
6344+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
6345+}
6346+
6347+#endif
6348+
6349+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
6350+
6351+struct squashfs_dir_index_2 {
6352+ unsigned int index:27;
6353+ unsigned int start_block:29;
6354+ unsigned char size;
6355+ unsigned char name[0];
6356+} __attribute__ ((packed));
6357+
6358+struct squashfs_base_inode_header_2 {
6359+ unsigned int inode_type:4;
6360+ unsigned int mode:12; /* protection */
6361+ unsigned int uid:8; /* index into uid table */
6362+ unsigned int guid:8; /* index into guid table */
6363+} __attribute__ ((packed));
6364+
6365+struct squashfs_ipc_inode_header_2 {
6366+ unsigned int inode_type:4;
6367+ unsigned int mode:12; /* protection */
6368+ unsigned int uid:8; /* index into uid table */
6369+ unsigned int guid:8; /* index into guid table */
6370+} __attribute__ ((packed));
6371+
6372+struct squashfs_dev_inode_header_2 {
6373+ unsigned int inode_type:4;
6374+ unsigned int mode:12; /* protection */
6375+ unsigned int uid:8; /* index into uid table */
6376+ unsigned int guid:8; /* index into guid table */
6377+ unsigned short rdev;
6378+} __attribute__ ((packed));
6379+
6380+struct squashfs_symlink_inode_header_2 {
6381+ unsigned int inode_type:4;
6382+ unsigned int mode:12; /* protection */
6383+ unsigned int uid:8; /* index into uid table */
6384+ unsigned int guid:8; /* index into guid table */
6385+ unsigned short symlink_size;
6386+ char symlink[0];
6387+} __attribute__ ((packed));
6388+
6389+struct squashfs_reg_inode_header_2 {
6390+ unsigned int inode_type:4;
6391+ unsigned int mode:12; /* protection */
6392+ unsigned int uid:8; /* index into uid table */
6393+ unsigned int guid:8; /* index into guid table */
6394+ unsigned int mtime;
6395+ unsigned int start_block;
6396+ unsigned int fragment;
6397+ unsigned int offset;
6398+ unsigned int file_size:32;
6399+ unsigned short block_list[0];
6400+} __attribute__ ((packed));
6401+
6402+struct squashfs_dir_inode_header_2 {
6403+ unsigned int inode_type:4;
6404+ unsigned int mode:12; /* protection */
6405+ unsigned int uid:8; /* index into uid table */
6406+ unsigned int guid:8; /* index into guid table */
6407+ unsigned int file_size:19;
6408+ unsigned int offset:13;
6409+ unsigned int mtime;
6410+ unsigned int start_block:24;
6411+} __attribute__ ((packed));
6412+
6413+struct squashfs_ldir_inode_header_2 {
6414+ unsigned int inode_type:4;
6415+ unsigned int mode:12; /* protection */
6416+ unsigned int uid:8; /* index into uid table */
6417+ unsigned int guid:8; /* index into guid table */
6418+ unsigned int file_size:27;
6419+ unsigned int offset:13;
6420+ unsigned int mtime;
6421+ unsigned int start_block:24;
6422+ unsigned int i_count:16;
6423+ struct squashfs_dir_index_2 index[0];
6424+} __attribute__ ((packed));
6425+
6426+union squashfs_inode_header_2 {
6427+ struct squashfs_base_inode_header_2 base;
6428+ struct squashfs_dev_inode_header_2 dev;
6429+ struct squashfs_symlink_inode_header_2 symlink;
6430+ struct squashfs_reg_inode_header_2 reg;
6431+ struct squashfs_dir_inode_header_2 dir;
6432+ struct squashfs_ldir_inode_header_2 ldir;
6433+ struct squashfs_ipc_inode_header_2 ipc;
6434+};
6435+
6436+struct squashfs_dir_header_2 {
6437+ unsigned int count:8;
6438+ unsigned int start_block:24;
6439+} __attribute__ ((packed));
6440+
6441+struct squashfs_dir_entry_2 {
6442+ unsigned int offset:13;
6443+ unsigned int type:3;
6444+ unsigned int size:8;
6445+ char name[0];
6446+} __attribute__ ((packed));
6447+
6448+struct squashfs_fragment_entry_2 {
6449+ unsigned int start_block;
6450+ unsigned int size;
6451+} __attribute__ ((packed));
6452+
6453+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
6454+ SQUASHFS_MEMSET(s, d, n);\
6455+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6456+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6457+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
6458+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
6459+
6460+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
6461+ SQUASHFS_SWAP_START\
6462+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
6463+}
6464+
6465+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
6466+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
6467+
6468+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
6469+ SQUASHFS_SWAP_START\
6470+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6471+ sizeof(struct squashfs_dev_inode_header_2)); \
6472+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
6473+}
6474+
6475+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
6476+ SQUASHFS_SWAP_START\
6477+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6478+ sizeof(struct squashfs_symlink_inode_header_2));\
6479+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
6480+}
6481+
6482+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
6483+ SQUASHFS_SWAP_START\
6484+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6485+ sizeof(struct squashfs_reg_inode_header_2));\
6486+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
6487+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
6488+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
6489+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\
6490+ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
6491+}
6492+
6493+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
6494+ SQUASHFS_SWAP_START\
6495+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6496+ sizeof(struct squashfs_dir_inode_header_2));\
6497+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
6498+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\
6499+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
6500+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
6501+}
6502+
6503+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
6504+ SQUASHFS_SWAP_START\
6505+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6506+ sizeof(struct squashfs_ldir_inode_header_2));\
6507+ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
6508+ SQUASHFS_SWAP((s)->offset, d, 59, 13);\
6509+ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
6510+ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
6511+ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
6512+}
6513+
6514+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
6515+ SQUASHFS_SWAP_START\
6516+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
6517+ SQUASHFS_SWAP((s)->index, d, 0, 27);\
6518+ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
6519+ SQUASHFS_SWAP((s)->size, d, 56, 8);\
6520+}
6521+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
6522+ SQUASHFS_SWAP_START\
6523+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
6524+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
6525+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
6526+}
6527+
6528+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
6529+ SQUASHFS_SWAP_START\
6530+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
6531+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
6532+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
6533+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
6534+}
6535+
6536+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
6537+ SQUASHFS_SWAP_START\
6538+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
6539+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
6540+ SQUASHFS_SWAP((s)->size, d, 32, 32);\
6541+}
6542+
6543+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
6544+
6545+/* fragment and fragment table defines */
6546+#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
6547+
6548+#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
6549+ SQUASHFS_METADATA_SIZE)
6550+
6551+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
6552+ SQUASHFS_METADATA_SIZE)
6553+
6554+#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
6555+ SQUASHFS_METADATA_SIZE - 1) / \
6556+ SQUASHFS_METADATA_SIZE)
6557+
6558+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
6559+ sizeof(int))
6560+
6561+#endif
6562+
6563+#ifdef __KERNEL__
6564+
6565+/*
6566+ * macros used to swap each structure entry, taking into account
6567+ * bitfields and different bitfield placing conventions on differing
6568+ * architectures
6569+ */
6570+
6571+#include <asm/byteorder.h>
6572+
6573+#ifdef __BIG_ENDIAN
6574+ /* convert from little endian to big endian */
6575+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
6576+ tbits, b_pos)
6577+#else
6578+ /* convert from big endian to little endian */
6579+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
6580+ tbits, 64 - tbits - b_pos)
6581+#endif
6582+
6583+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
6584+ b_pos = pos % 8;\
6585+ val = 0;\
6586+ s = (unsigned char *)p + (pos / 8);\
6587+ d = ((unsigned char *) &val) + 7;\
6588+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \
6589+ *d-- = *s++;\
6590+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
6591+}
6592+
6593+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
6594+
6595+#endif
6596+#endif
6597diff -uNr a/include/linux/squashfs_fs_i.h b/include/linux/squashfs_fs_i.h
6598--- a/include/linux/squashfs_fs_i.h 1969-12-31 16:00:00.000000000 -0800
6599+++ b/include/linux/squashfs_fs_i.h 2008-08-13 16:16:05.000000000 -0700
6600@@ -0,0 +1,45 @@
6601+#ifndef SQUASHFS_FS_I
6602+#define SQUASHFS_FS_I
6603+/*
6604+ * Squashfs
6605+ *
6606+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6607+ * Phillip Lougher <phillip@lougher.demon.co.uk>
6608+ *
6609+ * This program is free software; you can redistribute it and/or
6610+ * modify it under the terms of the GNU General Public License
6611+ * as published by the Free Software Foundation; either version 2,
6612+ * or (at your option) any later version.
6613+ *
6614+ * This program is distributed in the hope that it will be useful,
6615+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6617+ * GNU General Public License for more details.
6618+ *
6619+ * You should have received a copy of the GNU General Public License
6620+ * along with this program; if not, write to the Free Software
6621+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6622+ *
6623+ * squashfs_fs_i.h
6624+ */
6625+
6626+struct squashfs_inode_info {
6627+ long long start_block;
6628+ unsigned int offset;
6629+ union {
6630+ struct {
6631+ long long fragment_start_block;
6632+ unsigned int fragment_size;
6633+ unsigned int fragment_offset;
6634+ long long block_list_start;
6635+ } s1;
6636+ struct {
6637+ long long directory_index_start;
6638+ unsigned int directory_index_offset;
6639+ unsigned int directory_index_count;
6640+ unsigned int parent_inode;
6641+ } s2;
6642+ } u;
6643+ struct inode vfs_inode;
6644+};
6645+#endif
6646diff -uNr a/include/linux/squashfs_fs_sb.h b/include/linux/squashfs_fs_sb.h
6647--- a/include/linux/squashfs_fs_sb.h 1969-12-31 16:00:00.000000000 -0800
6648+++ b/include/linux/squashfs_fs_sb.h 2008-08-13 16:16:05.000000000 -0700
6649@@ -0,0 +1,78 @@
6650+#ifndef SQUASHFS_FS_SB
6651+#define SQUASHFS_FS_SB
6652+/*
6653+ * Squashfs
6654+ *
6655+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6656+ * Phillip Lougher <phillip@lougher.demon.co.uk>
6657+ *
6658+ * This program is free software; you can redistribute it and/or
6659+ * modify it under the terms of the GNU General Public License
6660+ * as published by the Free Software Foundation; either version 2,
6661+ * or (at your option) any later version.
6662+ *
6663+ * This program is distributed in the hope that it will be useful,
6664+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6665+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6666+ * GNU General Public License for more details.
6667+ *
6668+ * You should have received a copy of the GNU General Public License
6669+ * along with this program; if not, write to the Free Software
6670+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6671+ *
6672+ * squashfs_fs_sb.h
6673+ */
6674+
6675+#include <linux/squashfs_fs.h>
6676+
6677+struct squashfs_cache_entry {
6678+ long long block;
6679+ int length;
6680+ int locked;
6681+ long long next_index;
6682+ char pending;
6683+ char error;
6684+ int waiting;
6685+ wait_queue_head_t wait_queue;
6686+ char *data;
6687+};
6688+
6689+struct squashfs_cache {
6690+ char *name;
6691+ int entries;
6692+ int block_size;
6693+ int next_blk;
6694+ int waiting;
6695+ int unused_blks;
6696+ int use_vmalloc;
6697+ spinlock_t lock;
6698+ wait_queue_head_t wait_queue;
6699+ struct squashfs_cache_entry entry[0];
6700+};
6701+
6702+struct squashfs_sb_info {
6703+ struct squashfs_super_block sblk;
6704+ int devblksize;
6705+ int devblksize_log2;
6706+ int swap;
6707+ struct squashfs_cache *block_cache;
6708+ struct squashfs_cache *fragment_cache;
6709+ int next_meta_index;
6710+ unsigned int *id_table;
6711+ long long *fragment_index;
6712+ unsigned int *fragment_index_2;
6713+ char *read_page;
6714+ struct mutex read_data_mutex;
6715+ struct mutex read_page_mutex;
6716+ struct mutex meta_index_mutex;
6717+ struct meta_index *meta_index;
6718+ z_stream stream;
6719+ long long *inode_lookup_table;
6720+ int (*read_inode)(struct inode *i, squashfs_inode_t \
6721+ inode);
6722+ long long (*read_blocklist)(struct inode *inode, int \
6723+ index, int readahead_blks, char *block_list, \
6724+ unsigned short **block_p, unsigned int *bsize);
6725+ int (*read_fragment_index_table)(struct super_block *s);
6726+};
6727+#endif