0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/fs.h>
0024 #include <linux/vfs.h>
0025 #include <linux/slab.h>
0026
0027 #include "squashfs_fs.h"
0028 #include "squashfs_fs_sb.h"
0029 #include "squashfs.h"
0030
0031
0032
0033
0034
0035 int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
0036 u64 *fragment_block)
0037 {
0038 struct squashfs_sb_info *msblk = sb->s_fs_info;
0039 int block, offset, size;
0040 struct squashfs_fragment_entry fragment_entry;
0041 u64 start_block;
0042
0043 if (fragment >= msblk->fragments)
0044 return -EIO;
0045 block = SQUASHFS_FRAGMENT_INDEX(fragment);
0046 offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
0047
0048 start_block = le64_to_cpu(msblk->fragment_index[block]);
0049
0050 size = squashfs_read_metadata(sb, &fragment_entry, &start_block,
0051 &offset, sizeof(fragment_entry));
0052 if (size < 0)
0053 return size;
0054
0055 *fragment_block = le64_to_cpu(fragment_entry.start_block);
0056 return squashfs_block_size(fragment_entry.size);
0057 }
0058
0059
0060
0061
0062
0063 __le64 *squashfs_read_fragment_index_table(struct super_block *sb,
0064 u64 fragment_table_start, u64 next_table, unsigned int fragments)
0065 {
0066 unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments);
0067 __le64 *table;
0068
0069
0070
0071
0072
0073
0074 if (fragment_table_start + length > next_table)
0075 return ERR_PTR(-EINVAL);
0076
0077 table = squashfs_read_table(sb, fragment_table_start, length);
0078
0079
0080
0081
0082
0083 if (!IS_ERR(table) && le64_to_cpu(table[0]) >= fragment_table_start) {
0084 kfree(table);
0085 return ERR_PTR(-EINVAL);
0086 }
0087
0088 return table;
0089 }