aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/squashfs/Makefile2
-rw-r--r--fs/squashfs/squashfs.h6
-rw-r--r--fs/squashfs/squashfs_fs.h32
-rw-r--r--fs/squashfs/squashfs_fs_sb.h3
-rw-r--r--fs/squashfs/super.c22
-rw-r--r--fs/squashfs/xattr_id.c100
6 files changed, 161 insertions, 4 deletions
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile
index df8a19ef870d..c0da4a189cc4 100644
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -5,3 +5,5 @@
5obj-$(CONFIG_SQUASHFS) += squashfs.o 5obj-$(CONFIG_SQUASHFS) += squashfs.o
6squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o 6squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
7squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o 7squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
8squashfs-y += xattr_id.o
9
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
index fe2587af5512..133befe2f8b8 100644
--- a/fs/squashfs/squashfs.h
+++ b/fs/squashfs/squashfs.h
@@ -73,6 +73,12 @@ extern struct inode *squashfs_iget(struct super_block *, long long,
73 unsigned int); 73 unsigned int);
74extern int squashfs_read_inode(struct inode *, long long); 74extern int squashfs_read_inode(struct inode *, long long);
75 75
76/* xattr_id.c */
77extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
78 int *, long long *);
79extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
80 u64 *, int *);
81
76/* 82/*
77 * Inodes, files and decompressor operations 83 * Inodes, files and decompressor operations
78 */ 84 */
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index 79024245ea00..c654e863d3c0 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -174,6 +174,24 @@
174 174
175#define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\ 175#define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\
176 sizeof(u64)) 176 sizeof(u64))
177/* xattr id lookup table defines */
178#define SQUASHFS_XATTR_BYTES(A) ((A) * sizeof(struct squashfs_xattr_id))
179
180#define SQUASHFS_XATTR_BLOCK(A) (SQUASHFS_XATTR_BYTES(A) / \
181 SQUASHFS_METADATA_SIZE)
182
183#define SQUASHFS_XATTR_BLOCK_OFFSET(A) (SQUASHFS_XATTR_BYTES(A) % \
184 SQUASHFS_METADATA_SIZE)
185
186#define SQUASHFS_XATTR_BLOCKS(A) ((SQUASHFS_XATTR_BYTES(A) + \
187 SQUASHFS_METADATA_SIZE - 1) / \
188 SQUASHFS_METADATA_SIZE)
189
190#define SQUASHFS_XATTR_BLOCK_BYTES(A) (SQUASHFS_XATTR_BLOCKS(A) *\
191 sizeof(u64))
192#define SQUASHFS_XATTR_BLK(A) ((unsigned int) ((A) >> 16))
193
194#define SQUASHFS_XATTR_OFFSET(A) ((unsigned int) ((A) & 0xffff))
177 195
178/* cached data constants for filesystem */ 196/* cached data constants for filesystem */
179#define SQUASHFS_CACHED_BLKS 8 197#define SQUASHFS_CACHED_BLKS 8
@@ -228,7 +246,7 @@ struct squashfs_super_block {
228 __le64 root_inode; 246 __le64 root_inode;
229 __le64 bytes_used; 247 __le64 bytes_used;
230 __le64 id_table_start; 248 __le64 id_table_start;
231 __le64 xattr_table_start; 249 __le64 xattr_id_table_start;
232 __le64 inode_table_start; 250 __le64 inode_table_start;
233 __le64 directory_table_start; 251 __le64 directory_table_start;
234 __le64 fragment_table_start; 252 __le64 fragment_table_start;
@@ -377,4 +395,16 @@ struct squashfs_fragment_entry {
377 unsigned int unused; 395 unsigned int unused;
378}; 396};
379 397
398struct squashfs_xattr_id {
399 __le64 xattr;
400 __le32 count;
401 __le32 size;
402};
403
404struct squashfs_xattr_id_table {
405 __le64 xattr_table_start;
406 __le32 xattr_ids;
407 __le32 unused;
408};
409
380#endif 410#endif
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index 2e77dc547e25..d9037a5215f0 100644
--- a/fs/squashfs/squashfs_fs_sb.h
+++ b/fs/squashfs/squashfs_fs_sb.h
@@ -61,6 +61,7 @@ struct squashfs_sb_info {
61 int next_meta_index; 61 int next_meta_index;
62 __le64 *id_table; 62 __le64 *id_table;
63 __le64 *fragment_index; 63 __le64 *fragment_index;
64 __le64 *xattr_id_table;
64 struct mutex read_data_mutex; 65 struct mutex read_data_mutex;
65 struct mutex meta_index_mutex; 66 struct mutex meta_index_mutex;
66 struct meta_index *meta_index; 67 struct meta_index *meta_index;
@@ -68,9 +69,11 @@ struct squashfs_sb_info {
68 __le64 *inode_lookup_table; 69 __le64 *inode_lookup_table;
69 u64 inode_table; 70 u64 inode_table;
70 u64 directory_table; 71 u64 directory_table;
72 u64 xattr_table;
71 unsigned int block_size; 73 unsigned int block_size;
72 unsigned short block_log; 74 unsigned short block_log;
73 long long bytes_used; 75 long long bytes_used;
74 unsigned int inodes; 76 unsigned int inodes;
77 int xattr_ids;
75}; 78};
76#endif 79#endif
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 48b6f4a385a6..c4dfc393fa52 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -36,6 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/magic.h> 38#include <linux/magic.h>
39#include <linux/xattr.h>
39 40
40#include "squashfs_fs.h" 41#include "squashfs_fs.h"
41#include "squashfs_fs_sb.h" 42#include "squashfs_fs_sb.h"
@@ -82,7 +83,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
82 long long root_inode; 83 long long root_inode;
83 unsigned short flags; 84 unsigned short flags;
84 unsigned int fragments; 85 unsigned int fragments;
85 u64 lookup_table_start; 86 u64 lookup_table_start, xattr_id_table_start;
86 int err; 87 int err;
87 88
88 TRACE("Entered squashfs_fill_superblock\n"); 89 TRACE("Entered squashfs_fill_superblock\n");
@@ -143,7 +144,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
143 * Check if there's xattrs in the filesystem. These are not 144 * Check if there's xattrs in the filesystem. These are not
144 * supported in this version, so warn that they will be ignored. 145 * supported in this version, so warn that they will be ignored.
145 */ 146 */
146 if (le64_to_cpu(sblk->xattr_table_start) != SQUASHFS_INVALID_BLK) 147 if (le64_to_cpu(sblk->xattr_id_table_start) != SQUASHFS_INVALID_BLK)
147 ERROR("Xattrs in filesystem, these will be ignored\n"); 148 ERROR("Xattrs in filesystem, these will be ignored\n");
148 149
149 /* Check the filesystem does not extend beyond the end of the 150 /* Check the filesystem does not extend beyond the end of the
@@ -253,7 +254,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
253allocate_lookup_table: 254allocate_lookup_table:
254 lookup_table_start = le64_to_cpu(sblk->lookup_table_start); 255 lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
255 if (lookup_table_start == SQUASHFS_INVALID_BLK) 256 if (lookup_table_start == SQUASHFS_INVALID_BLK)
256 goto allocate_root; 257 goto allocate_xattr_table;
257 258
258 /* Allocate and read inode lookup table */ 259 /* Allocate and read inode lookup table */
259 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, 260 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
@@ -266,6 +267,19 @@ allocate_lookup_table:
266 267
267 sb->s_export_op = &squashfs_export_ops; 268 sb->s_export_op = &squashfs_export_ops;
268 269
270allocate_xattr_table:
271 xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
272 if (xattr_id_table_start == SQUASHFS_INVALID_BLK)
273 goto allocate_root;
274
275 /* Allocate and read xattr id lookup table */
276 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
277 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
278 if (IS_ERR(msblk->xattr_id_table)) {
279 err = PTR_ERR(msblk->xattr_id_table);
280 msblk->xattr_id_table = NULL;
281 goto failed_mount;
282 }
269allocate_root: 283allocate_root:
270 root = new_inode(sb); 284 root = new_inode(sb);
271 if (!root) { 285 if (!root) {
@@ -301,6 +315,7 @@ failed_mount:
301 kfree(msblk->inode_lookup_table); 315 kfree(msblk->inode_lookup_table);
302 kfree(msblk->fragment_index); 316 kfree(msblk->fragment_index);
303 kfree(msblk->id_table); 317 kfree(msblk->id_table);
318 kfree(msblk->xattr_id_table);
304 kfree(sb->s_fs_info); 319 kfree(sb->s_fs_info);
305 sb->s_fs_info = NULL; 320 sb->s_fs_info = NULL;
306 kfree(sblk); 321 kfree(sblk);
@@ -355,6 +370,7 @@ static void squashfs_put_super(struct super_block *sb)
355 kfree(sbi->fragment_index); 370 kfree(sbi->fragment_index);
356 kfree(sbi->meta_index); 371 kfree(sbi->meta_index);
357 kfree(sbi->inode_lookup_table); 372 kfree(sbi->inode_lookup_table);
373 kfree(sbi->xattr_id_table);
358 kfree(sb->s_fs_info); 374 kfree(sb->s_fs_info);
359 sb->s_fs_info = NULL; 375 sb->s_fs_info = NULL;
360 } 376 }
diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c
new file mode 100644
index 000000000000..a74101244a98
--- /dev/null
+++ b/fs/squashfs/xattr_id.c
@@ -0,0 +1,100 @@
1/*
2 * Squashfs - a compressed read only filesystem for Linux
3 *
4 * Copyright (c) 2010
5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 * xattr_id.c
22 */
23
24/*
25 * This file implements code to map the 32-bit xattr id stored in the inode
26 * into the on disk location of the xattr data.
27 */
28
29#include <linux/fs.h>
30#include <linux/vfs.h>
31#include <linux/slab.h>
32
33#include "squashfs_fs.h"
34#include "squashfs_fs_sb.h"
35#include "squashfs_fs_i.h"
36#include "squashfs.h"
37
38/*
39 * Map xattr id using the xattr id look up table
40 */
41int squashfs_xattr_lookup(struct super_block *sb, unsigned int index,
42 int *count, int *size, long long *xattr)
43{
44 struct squashfs_sb_info *msblk = sb->s_fs_info;
45 int block = SQUASHFS_XATTR_BLOCK(index);
46 int offset = SQUASHFS_XATTR_BLOCK_OFFSET(index);
47 u64 start_block = le64_to_cpu(msblk->xattr_id_table[block]);
48 struct squashfs_xattr_id id;
49 int err;
50
51 err = squashfs_read_metadata(sb, &id, &start_block, &offset,
52 sizeof(id));
53 if (err < 0)
54 return err;
55
56 *xattr = le64_to_cpu(id.xattr);
57 *size = le32_to_cpu(id.size);
58 *count = le32_to_cpu(id.count);
59 return 0;
60}
61
62
63/*
64 * Read uncompressed xattr id lookup table indexes from disk into memory
65 */
66__le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start,
67 u64 *xattr_table_start, int *xattr_ids)
68{
69 unsigned int len;
70 __le64 *xid_table;
71 struct squashfs_xattr_id_table id_table;
72 int err;
73
74 err = squashfs_read_table(sb, &id_table, start, sizeof(id_table));
75 if (err < 0) {
76 ERROR("unable to read xattr id table\n");
77 return ERR_PTR(err);
78 }
79 *xattr_table_start = le64_to_cpu(id_table.xattr_table_start);
80 *xattr_ids = le32_to_cpu(id_table.xattr_ids);
81 len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids);
82
83 TRACE("In read_xattr_index_table, length %d\n", len);
84
85 /* Allocate xattr id lookup table indexes */
86 xid_table = kmalloc(len, GFP_KERNEL);
87 if (xid_table == NULL) {
88 ERROR("Failed to allocate xattr id index table\n");
89 return ERR_PTR(-ENOMEM);
90 }
91
92 err = squashfs_read_table(sb, xid_table, start + sizeof(id_table), len);
93 if (err < 0) {
94 ERROR("unable to read xattr id index table\n");
95 kfree(xid_table);
96 return ERR_PTR(err);
97 }
98
99 return xid_table;
100}