Commit 4b5397dc24ab12afaac85be3d0863b7f6eb8b0f0
1 parent
b57f95a382
Exists in
master
and in
4 other branches
squashfs: add xattr id support
This patch adds support for mapping xattr ids (stored in inodes) into the on-disk location of the xattrs themselves. Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Showing 6 changed files with 161 additions and 4 deletions Side-by-side Diff
fs/squashfs/Makefile
fs/squashfs/squashfs.h
... | ... | @@ -73,6 +73,12 @@ |
73 | 73 | unsigned int); |
74 | 74 | extern int squashfs_read_inode(struct inode *, long long); |
75 | 75 | |
76 | +/* xattr_id.c */ | |
77 | +extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, | |
78 | + int *, long long *); | |
79 | +extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64, | |
80 | + u64 *, int *); | |
81 | + | |
76 | 82 | /* |
77 | 83 | * Inodes, files and decompressor operations |
78 | 84 | */ |
fs/squashfs/squashfs_fs.h
... | ... | @@ -174,7 +174,25 @@ |
174 | 174 | |
175 | 175 | #define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\ |
176 | 176 | sizeof(u64)) |
177 | +/* xattr id lookup table defines */ | |
178 | +#define SQUASHFS_XATTR_BYTES(A) ((A) * sizeof(struct squashfs_xattr_id)) | |
177 | 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)) | |
195 | + | |
178 | 196 | /* cached data constants for filesystem */ |
179 | 197 | #define SQUASHFS_CACHED_BLKS 8 |
180 | 198 | |
... | ... | @@ -228,7 +246,7 @@ |
228 | 246 | __le64 root_inode; |
229 | 247 | __le64 bytes_used; |
230 | 248 | __le64 id_table_start; |
231 | - __le64 xattr_table_start; | |
249 | + __le64 xattr_id_table_start; | |
232 | 250 | __le64 inode_table_start; |
233 | 251 | __le64 directory_table_start; |
234 | 252 | __le64 fragment_table_start; |
... | ... | @@ -375,6 +393,18 @@ |
375 | 393 | __le64 start_block; |
376 | 394 | __le32 size; |
377 | 395 | unsigned int unused; |
396 | +}; | |
397 | + | |
398 | +struct squashfs_xattr_id { | |
399 | + __le64 xattr; | |
400 | + __le32 count; | |
401 | + __le32 size; | |
402 | +}; | |
403 | + | |
404 | +struct squashfs_xattr_id_table { | |
405 | + __le64 xattr_table_start; | |
406 | + __le32 xattr_ids; | |
407 | + __le32 unused; | |
378 | 408 | }; |
379 | 409 | |
380 | 410 | #endif |
fs/squashfs/squashfs_fs_sb.h
... | ... | @@ -61,6 +61,7 @@ |
61 | 61 | int next_meta_index; |
62 | 62 | __le64 *id_table; |
63 | 63 | __le64 *fragment_index; |
64 | + __le64 *xattr_id_table; | |
64 | 65 | struct mutex read_data_mutex; |
65 | 66 | struct mutex meta_index_mutex; |
66 | 67 | struct meta_index *meta_index; |
67 | 68 | |
... | ... | @@ -68,10 +69,12 @@ |
68 | 69 | __le64 *inode_lookup_table; |
69 | 70 | u64 inode_table; |
70 | 71 | u64 directory_table; |
72 | + u64 xattr_table; | |
71 | 73 | unsigned int block_size; |
72 | 74 | unsigned short block_log; |
73 | 75 | long long bytes_used; |
74 | 76 | unsigned int inodes; |
77 | + int xattr_ids; | |
75 | 78 | }; |
76 | 79 | #endif |
fs/squashfs/super.c
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | #include <linux/init.h> |
37 | 37 | #include <linux/module.h> |
38 | 38 | #include <linux/magic.h> |
39 | +#include <linux/xattr.h> | |
39 | 40 | |
40 | 41 | #include "squashfs_fs.h" |
41 | 42 | #include "squashfs_fs_sb.h" |
... | ... | @@ -82,7 +83,7 @@ |
82 | 83 | long long root_inode; |
83 | 84 | unsigned short flags; |
84 | 85 | unsigned int fragments; |
85 | - u64 lookup_table_start; | |
86 | + u64 lookup_table_start, xattr_id_table_start; | |
86 | 87 | int err; |
87 | 88 | |
88 | 89 | TRACE("Entered squashfs_fill_superblock\n"); |
... | ... | @@ -143,7 +144,7 @@ |
143 | 144 | * Check if there's xattrs in the filesystem. These are not |
144 | 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 | 148 | ERROR("Xattrs in filesystem, these will be ignored\n"); |
148 | 149 | |
149 | 150 | /* Check the filesystem does not extend beyond the end of the |
... | ... | @@ -253,7 +254,7 @@ |
253 | 254 | allocate_lookup_table: |
254 | 255 | lookup_table_start = le64_to_cpu(sblk->lookup_table_start); |
255 | 256 | if (lookup_table_start == SQUASHFS_INVALID_BLK) |
256 | - goto allocate_root; | |
257 | + goto allocate_xattr_table; | |
257 | 258 | |
258 | 259 | /* Allocate and read inode lookup table */ |
259 | 260 | msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, |
... | ... | @@ -266,6 +267,19 @@ |
266 | 267 | |
267 | 268 | sb->s_export_op = &squashfs_export_ops; |
268 | 269 | |
270 | +allocate_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 | + } | |
269 | 283 | allocate_root: |
270 | 284 | root = new_inode(sb); |
271 | 285 | if (!root) { |
... | ... | @@ -301,6 +315,7 @@ |
301 | 315 | kfree(msblk->inode_lookup_table); |
302 | 316 | kfree(msblk->fragment_index); |
303 | 317 | kfree(msblk->id_table); |
318 | + kfree(msblk->xattr_id_table); | |
304 | 319 | kfree(sb->s_fs_info); |
305 | 320 | sb->s_fs_info = NULL; |
306 | 321 | kfree(sblk); |
... | ... | @@ -355,6 +370,7 @@ |
355 | 370 | kfree(sbi->fragment_index); |
356 | 371 | kfree(sbi->meta_index); |
357 | 372 | kfree(sbi->inode_lookup_table); |
373 | + kfree(sbi->xattr_id_table); | |
358 | 374 | kfree(sb->s_fs_info); |
359 | 375 | sb->s_fs_info = NULL; |
360 | 376 | } |
fs/squashfs/xattr_id.c
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 | + */ | |
41 | +int 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 | +} |