Commit 67f66cc6c728de183d9d43c243cb163c1ebd8e04

Authored by Phillip Lougher
1 parent f41d207cbe

squashfs: add new extended inode types

Add new extended inode types that store the xattr_id field.
Also add the necessary code changes to make xattrs visibile.

Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>

Showing 6 changed files with 135 additions and 16 deletions Inline Diff

1 /* 1 /*
2 * Squashfs - a compressed read only filesystem for Linux 2 * Squashfs - a compressed read only filesystem for Linux
3 * 3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@lougher.demon.co.uk> 5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2, 9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version. 10 * or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * 20 *
21 * inode.c 21 * inode.c
22 */ 22 */
23 23
24 /* 24 /*
25 * This file implements code to create and read inodes from disk. 25 * This file implements code to create and read inodes from disk.
26 * 26 *
27 * Inodes in Squashfs are identified by a 48-bit inode which encodes the 27 * Inodes in Squashfs are identified by a 48-bit inode which encodes the
28 * location of the compressed metadata block containing the inode, and the byte 28 * location of the compressed metadata block containing the inode, and the byte
29 * offset into that block where the inode is placed (<block, offset>). 29 * offset into that block where the inode is placed (<block, offset>).
30 * 30 *
31 * To maximise compression there are different inodes for each file type 31 * To maximise compression there are different inodes for each file type
32 * (regular file, directory, device, etc.), the inode contents and length 32 * (regular file, directory, device, etc.), the inode contents and length
33 * varying with the type. 33 * varying with the type.
34 * 34 *
35 * To further maximise compression, two types of regular file inode and 35 * To further maximise compression, two types of regular file inode and
36 * directory inode are defined: inodes optimised for frequently occurring 36 * directory inode are defined: inodes optimised for frequently occurring
37 * regular files and directories, and extended types where extra 37 * regular files and directories, and extended types where extra
38 * information has to be stored. 38 * information has to be stored.
39 */ 39 */
40 40
41 #include <linux/fs.h> 41 #include <linux/fs.h>
42 #include <linux/vfs.h> 42 #include <linux/vfs.h>
43 #include <linux/xattr.h>
43 44
44 #include "squashfs_fs.h" 45 #include "squashfs_fs.h"
45 #include "squashfs_fs_sb.h" 46 #include "squashfs_fs_sb.h"
46 #include "squashfs_fs_i.h" 47 #include "squashfs_fs_i.h"
47 #include "squashfs.h" 48 #include "squashfs.h"
48 49
49 /* 50 /*
50 * Initialise VFS inode with the base inode information common to all 51 * Initialise VFS inode with the base inode information common to all
51 * Squashfs inode types. Sqsh_ino contains the unswapped base inode 52 * Squashfs inode types. Sqsh_ino contains the unswapped base inode
52 * off disk. 53 * off disk.
53 */ 54 */
54 static int squashfs_new_inode(struct super_block *sb, struct inode *inode, 55 static int squashfs_new_inode(struct super_block *sb, struct inode *inode,
55 struct squashfs_base_inode *sqsh_ino) 56 struct squashfs_base_inode *sqsh_ino)
56 { 57 {
57 int err; 58 int err;
58 59
59 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &inode->i_uid); 60 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &inode->i_uid);
60 if (err) 61 if (err)
61 return err; 62 return err;
62 63
63 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &inode->i_gid); 64 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &inode->i_gid);
64 if (err) 65 if (err)
65 return err; 66 return err;
66 67
67 inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); 68 inode->i_ino = le32_to_cpu(sqsh_ino->inode_number);
68 inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime); 69 inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime);
69 inode->i_atime.tv_sec = inode->i_mtime.tv_sec; 70 inode->i_atime.tv_sec = inode->i_mtime.tv_sec;
70 inode->i_ctime.tv_sec = inode->i_mtime.tv_sec; 71 inode->i_ctime.tv_sec = inode->i_mtime.tv_sec;
71 inode->i_mode = le16_to_cpu(sqsh_ino->mode); 72 inode->i_mode = le16_to_cpu(sqsh_ino->mode);
72 inode->i_size = 0; 73 inode->i_size = 0;
73 74
74 return err; 75 return err;
75 } 76 }
76 77
77 78
78 struct inode *squashfs_iget(struct super_block *sb, long long ino, 79 struct inode *squashfs_iget(struct super_block *sb, long long ino,
79 unsigned int ino_number) 80 unsigned int ino_number)
80 { 81 {
81 struct inode *inode = iget_locked(sb, ino_number); 82 struct inode *inode = iget_locked(sb, ino_number);
82 int err; 83 int err;
83 84
84 TRACE("Entered squashfs_iget\n"); 85 TRACE("Entered squashfs_iget\n");
85 86
86 if (!inode) 87 if (!inode)
87 return ERR_PTR(-ENOMEM); 88 return ERR_PTR(-ENOMEM);
88 if (!(inode->i_state & I_NEW)) 89 if (!(inode->i_state & I_NEW))
89 return inode; 90 return inode;
90 91
91 err = squashfs_read_inode(inode, ino); 92 err = squashfs_read_inode(inode, ino);
92 if (err) { 93 if (err) {
93 iget_failed(inode); 94 iget_failed(inode);
94 return ERR_PTR(err); 95 return ERR_PTR(err);
95 } 96 }
96 97
97 unlock_new_inode(inode); 98 unlock_new_inode(inode);
98 return inode; 99 return inode;
99 } 100 }
100 101
101 102
102 /* 103 /*
103 * Initialise VFS inode by reading inode from inode table (compressed 104 * Initialise VFS inode by reading inode from inode table (compressed
104 * metadata). The format and amount of data read depends on type. 105 * metadata). The format and amount of data read depends on type.
105 */ 106 */
106 int squashfs_read_inode(struct inode *inode, long long ino) 107 int squashfs_read_inode(struct inode *inode, long long ino)
107 { 108 {
108 struct super_block *sb = inode->i_sb; 109 struct super_block *sb = inode->i_sb;
109 struct squashfs_sb_info *msblk = sb->s_fs_info; 110 struct squashfs_sb_info *msblk = sb->s_fs_info;
110 u64 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table; 111 u64 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table;
111 int err, type, offset = SQUASHFS_INODE_OFFSET(ino); 112 int err, type, offset = SQUASHFS_INODE_OFFSET(ino);
112 union squashfs_inode squashfs_ino; 113 union squashfs_inode squashfs_ino;
113 struct squashfs_base_inode *sqshb_ino = &squashfs_ino.base; 114 struct squashfs_base_inode *sqshb_ino = &squashfs_ino.base;
115 int xattr_id = SQUASHFS_INVALID_XATTR;
114 116
115 TRACE("Entered squashfs_read_inode\n"); 117 TRACE("Entered squashfs_read_inode\n");
116 118
117 /* 119 /*
118 * Read inode base common to all inode types. 120 * Read inode base common to all inode types.
119 */ 121 */
120 err = squashfs_read_metadata(sb, sqshb_ino, &block, 122 err = squashfs_read_metadata(sb, sqshb_ino, &block,
121 &offset, sizeof(*sqshb_ino)); 123 &offset, sizeof(*sqshb_ino));
122 if (err < 0) 124 if (err < 0)
123 goto failed_read; 125 goto failed_read;
124 126
125 err = squashfs_new_inode(sb, inode, sqshb_ino); 127 err = squashfs_new_inode(sb, inode, sqshb_ino);
126 if (err) 128 if (err)
127 goto failed_read; 129 goto failed_read;
128 130
129 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table; 131 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table;
130 offset = SQUASHFS_INODE_OFFSET(ino); 132 offset = SQUASHFS_INODE_OFFSET(ino);
131 133
132 type = le16_to_cpu(sqshb_ino->inode_type); 134 type = le16_to_cpu(sqshb_ino->inode_type);
133 switch (type) { 135 switch (type) {
134 case SQUASHFS_REG_TYPE: { 136 case SQUASHFS_REG_TYPE: {
135 unsigned int frag_offset, frag; 137 unsigned int frag_offset, frag;
136 int frag_size; 138 int frag_size;
137 u64 frag_blk; 139 u64 frag_blk;
138 struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg; 140 struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg;
139 141
140 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 142 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
141 sizeof(*sqsh_ino)); 143 sizeof(*sqsh_ino));
142 if (err < 0) 144 if (err < 0)
143 goto failed_read; 145 goto failed_read;
144 146
145 frag = le32_to_cpu(sqsh_ino->fragment); 147 frag = le32_to_cpu(sqsh_ino->fragment);
146 if (frag != SQUASHFS_INVALID_FRAG) { 148 if (frag != SQUASHFS_INVALID_FRAG) {
147 frag_offset = le32_to_cpu(sqsh_ino->offset); 149 frag_offset = le32_to_cpu(sqsh_ino->offset);
148 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); 150 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
149 if (frag_size < 0) { 151 if (frag_size < 0) {
150 err = frag_size; 152 err = frag_size;
151 goto failed_read; 153 goto failed_read;
152 } 154 }
153 } else { 155 } else {
154 frag_blk = SQUASHFS_INVALID_BLK; 156 frag_blk = SQUASHFS_INVALID_BLK;
155 frag_size = 0; 157 frag_size = 0;
156 frag_offset = 0; 158 frag_offset = 0;
157 } 159 }
158 160
159 inode->i_nlink = 1; 161 inode->i_nlink = 1;
160 inode->i_size = le32_to_cpu(sqsh_ino->file_size); 162 inode->i_size = le32_to_cpu(sqsh_ino->file_size);
161 inode->i_fop = &generic_ro_fops; 163 inode->i_fop = &generic_ro_fops;
162 inode->i_mode |= S_IFREG; 164 inode->i_mode |= S_IFREG;
163 inode->i_blocks = ((inode->i_size - 1) >> 9) + 1; 165 inode->i_blocks = ((inode->i_size - 1) >> 9) + 1;
164 squashfs_i(inode)->fragment_block = frag_blk; 166 squashfs_i(inode)->fragment_block = frag_blk;
165 squashfs_i(inode)->fragment_size = frag_size; 167 squashfs_i(inode)->fragment_size = frag_size;
166 squashfs_i(inode)->fragment_offset = frag_offset; 168 squashfs_i(inode)->fragment_offset = frag_offset;
167 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 169 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
168 squashfs_i(inode)->block_list_start = block; 170 squashfs_i(inode)->block_list_start = block;
169 squashfs_i(inode)->offset = offset; 171 squashfs_i(inode)->offset = offset;
170 inode->i_data.a_ops = &squashfs_aops; 172 inode->i_data.a_ops = &squashfs_aops;
171 173
172 TRACE("File inode %x:%x, start_block %llx, block_list_start " 174 TRACE("File inode %x:%x, start_block %llx, block_list_start "
173 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino), 175 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino),
174 offset, squashfs_i(inode)->start, block, offset); 176 offset, squashfs_i(inode)->start, block, offset);
175 break; 177 break;
176 } 178 }
177 case SQUASHFS_LREG_TYPE: { 179 case SQUASHFS_LREG_TYPE: {
178 unsigned int frag_offset, frag; 180 unsigned int frag_offset, frag;
179 int frag_size; 181 int frag_size;
180 u64 frag_blk; 182 u64 frag_blk;
181 struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; 183 struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg;
182 184
183 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 185 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
184 sizeof(*sqsh_ino)); 186 sizeof(*sqsh_ino));
185 if (err < 0) 187 if (err < 0)
186 goto failed_read; 188 goto failed_read;
187 189
188 frag = le32_to_cpu(sqsh_ino->fragment); 190 frag = le32_to_cpu(sqsh_ino->fragment);
189 if (frag != SQUASHFS_INVALID_FRAG) { 191 if (frag != SQUASHFS_INVALID_FRAG) {
190 frag_offset = le32_to_cpu(sqsh_ino->offset); 192 frag_offset = le32_to_cpu(sqsh_ino->offset);
191 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); 193 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
192 if (frag_size < 0) { 194 if (frag_size < 0) {
193 err = frag_size; 195 err = frag_size;
194 goto failed_read; 196 goto failed_read;
195 } 197 }
196 } else { 198 } else {
197 frag_blk = SQUASHFS_INVALID_BLK; 199 frag_blk = SQUASHFS_INVALID_BLK;
198 frag_size = 0; 200 frag_size = 0;
199 frag_offset = 0; 201 frag_offset = 0;
200 } 202 }
201 203
204 xattr_id = le32_to_cpu(sqsh_ino->xattr);
202 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink); 205 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
203 inode->i_size = le64_to_cpu(sqsh_ino->file_size); 206 inode->i_size = le64_to_cpu(sqsh_ino->file_size);
207 inode->i_op = &squashfs_inode_ops;
204 inode->i_fop = &generic_ro_fops; 208 inode->i_fop = &generic_ro_fops;
205 inode->i_mode |= S_IFREG; 209 inode->i_mode |= S_IFREG;
206 inode->i_blocks = ((inode->i_size - 210 inode->i_blocks = ((inode->i_size -
207 le64_to_cpu(sqsh_ino->sparse) - 1) >> 9) + 1; 211 le64_to_cpu(sqsh_ino->sparse) - 1) >> 9) + 1;
208 212
209 squashfs_i(inode)->fragment_block = frag_blk; 213 squashfs_i(inode)->fragment_block = frag_blk;
210 squashfs_i(inode)->fragment_size = frag_size; 214 squashfs_i(inode)->fragment_size = frag_size;
211 squashfs_i(inode)->fragment_offset = frag_offset; 215 squashfs_i(inode)->fragment_offset = frag_offset;
212 squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block); 216 squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block);
213 squashfs_i(inode)->block_list_start = block; 217 squashfs_i(inode)->block_list_start = block;
214 squashfs_i(inode)->offset = offset; 218 squashfs_i(inode)->offset = offset;
215 inode->i_data.a_ops = &squashfs_aops; 219 inode->i_data.a_ops = &squashfs_aops;
216 220
217 TRACE("File inode %x:%x, start_block %llx, block_list_start " 221 TRACE("File inode %x:%x, start_block %llx, block_list_start "
218 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino), 222 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino),
219 offset, squashfs_i(inode)->start, block, offset); 223 offset, squashfs_i(inode)->start, block, offset);
220 break; 224 break;
221 } 225 }
222 case SQUASHFS_DIR_TYPE: { 226 case SQUASHFS_DIR_TYPE: {
223 struct squashfs_dir_inode *sqsh_ino = &squashfs_ino.dir; 227 struct squashfs_dir_inode *sqsh_ino = &squashfs_ino.dir;
224 228
225 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 229 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
226 sizeof(*sqsh_ino)); 230 sizeof(*sqsh_ino));
227 if (err < 0) 231 if (err < 0)
228 goto failed_read; 232 goto failed_read;
229 233
230 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink); 234 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
231 inode->i_size = le16_to_cpu(sqsh_ino->file_size); 235 inode->i_size = le16_to_cpu(sqsh_ino->file_size);
232 inode->i_op = &squashfs_dir_inode_ops; 236 inode->i_op = &squashfs_dir_inode_ops;
233 inode->i_fop = &squashfs_dir_ops; 237 inode->i_fop = &squashfs_dir_ops;
234 inode->i_mode |= S_IFDIR; 238 inode->i_mode |= S_IFDIR;
235 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 239 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
236 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset); 240 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset);
237 squashfs_i(inode)->dir_idx_cnt = 0; 241 squashfs_i(inode)->dir_idx_cnt = 0;
238 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode); 242 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode);
239 243
240 TRACE("Directory inode %x:%x, start_block %llx, offset %x\n", 244 TRACE("Directory inode %x:%x, start_block %llx, offset %x\n",
241 SQUASHFS_INODE_BLK(ino), offset, 245 SQUASHFS_INODE_BLK(ino), offset,
242 squashfs_i(inode)->start, 246 squashfs_i(inode)->start,
243 le16_to_cpu(sqsh_ino->offset)); 247 le16_to_cpu(sqsh_ino->offset));
244 break; 248 break;
245 } 249 }
246 case SQUASHFS_LDIR_TYPE: { 250 case SQUASHFS_LDIR_TYPE: {
247 struct squashfs_ldir_inode *sqsh_ino = &squashfs_ino.ldir; 251 struct squashfs_ldir_inode *sqsh_ino = &squashfs_ino.ldir;
248 252
249 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 253 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
250 sizeof(*sqsh_ino)); 254 sizeof(*sqsh_ino));
251 if (err < 0) 255 if (err < 0)
252 goto failed_read; 256 goto failed_read;
253 257
258 xattr_id = le32_to_cpu(sqsh_ino->xattr);
254 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink); 259 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
255 inode->i_size = le32_to_cpu(sqsh_ino->file_size); 260 inode->i_size = le32_to_cpu(sqsh_ino->file_size);
256 inode->i_op = &squashfs_dir_inode_ops; 261 inode->i_op = &squashfs_dir_inode_ops;
257 inode->i_fop = &squashfs_dir_ops; 262 inode->i_fop = &squashfs_dir_ops;
258 inode->i_mode |= S_IFDIR; 263 inode->i_mode |= S_IFDIR;
259 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 264 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
260 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset); 265 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset);
261 squashfs_i(inode)->dir_idx_start = block; 266 squashfs_i(inode)->dir_idx_start = block;
262 squashfs_i(inode)->dir_idx_offset = offset; 267 squashfs_i(inode)->dir_idx_offset = offset;
263 squashfs_i(inode)->dir_idx_cnt = le16_to_cpu(sqsh_ino->i_count); 268 squashfs_i(inode)->dir_idx_cnt = le16_to_cpu(sqsh_ino->i_count);
264 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode); 269 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode);
265 270
266 TRACE("Long directory inode %x:%x, start_block %llx, offset " 271 TRACE("Long directory inode %x:%x, start_block %llx, offset "
267 "%x\n", SQUASHFS_INODE_BLK(ino), offset, 272 "%x\n", SQUASHFS_INODE_BLK(ino), offset,
268 squashfs_i(inode)->start, 273 squashfs_i(inode)->start,
269 le16_to_cpu(sqsh_ino->offset)); 274 le16_to_cpu(sqsh_ino->offset));
270 break; 275 break;
271 } 276 }
272 case SQUASHFS_SYMLINK_TYPE: 277 case SQUASHFS_SYMLINK_TYPE:
273 case SQUASHFS_LSYMLINK_TYPE: { 278 case SQUASHFS_LSYMLINK_TYPE: {
274 struct squashfs_symlink_inode *sqsh_ino = &squashfs_ino.symlink; 279 struct squashfs_symlink_inode *sqsh_ino = &squashfs_ino.symlink;
275 280
276 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 281 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
277 sizeof(*sqsh_ino)); 282 sizeof(*sqsh_ino));
278 if (err < 0) 283 if (err < 0)
279 goto failed_read; 284 goto failed_read;
280 285
281 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink); 286 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
282 inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); 287 inode->i_size = le32_to_cpu(sqsh_ino->symlink_size);
283 inode->i_op = &page_symlink_inode_operations; 288 inode->i_op = &squashfs_symlink_inode_ops;
284 inode->i_data.a_ops = &squashfs_symlink_aops; 289 inode->i_data.a_ops = &squashfs_symlink_aops;
285 inode->i_mode |= S_IFLNK; 290 inode->i_mode |= S_IFLNK;
286 squashfs_i(inode)->start = block; 291 squashfs_i(inode)->start = block;
287 squashfs_i(inode)->offset = offset; 292 squashfs_i(inode)->offset = offset;
288 293
294 if (type == SQUASHFS_LSYMLINK_TYPE) {
295 __le32 xattr;
296
297 err = squashfs_read_metadata(sb, NULL, &block,
298 &offset, inode->i_size);
299 if (err < 0)
300 goto failed_read;
301 err = squashfs_read_metadata(sb, &xattr, &block,
302 &offset, sizeof(xattr));
303 if (err < 0)
304 goto failed_read;
305 xattr_id = le32_to_cpu(xattr);
306 }
307
289 TRACE("Symbolic link inode %x:%x, start_block %llx, offset " 308 TRACE("Symbolic link inode %x:%x, start_block %llx, offset "
290 "%x\n", SQUASHFS_INODE_BLK(ino), offset, 309 "%x\n", SQUASHFS_INODE_BLK(ino), offset,
291 block, offset); 310 block, offset);
292 break; 311 break;
293 } 312 }
294 case SQUASHFS_BLKDEV_TYPE: 313 case SQUASHFS_BLKDEV_TYPE:
295 case SQUASHFS_CHRDEV_TYPE: 314 case SQUASHFS_CHRDEV_TYPE: {
296 case SQUASHFS_LBLKDEV_TYPE:
297 case SQUASHFS_LCHRDEV_TYPE: {
298 struct squashfs_dev_inode *sqsh_ino = &squashfs_ino.dev; 315 struct squashfs_dev_inode *sqsh_ino = &squashfs_ino.dev;
299 unsigned int rdev; 316 unsigned int rdev;
300 317
301 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 318 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
302 sizeof(*sqsh_ino)); 319 sizeof(*sqsh_ino));
303 if (err < 0) 320 if (err < 0)
304 goto failed_read; 321 goto failed_read;
305 322
306 if (type == SQUASHFS_CHRDEV_TYPE) 323 if (type == SQUASHFS_CHRDEV_TYPE)
307 inode->i_mode |= S_IFCHR; 324 inode->i_mode |= S_IFCHR;
308 else 325 else
309 inode->i_mode |= S_IFBLK; 326 inode->i_mode |= S_IFBLK;
310 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink); 327 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
311 rdev = le32_to_cpu(sqsh_ino->rdev); 328 rdev = le32_to_cpu(sqsh_ino->rdev);
312 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); 329 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
313 330
314 TRACE("Device inode %x:%x, rdev %x\n", 331 TRACE("Device inode %x:%x, rdev %x\n",
315 SQUASHFS_INODE_BLK(ino), offset, rdev); 332 SQUASHFS_INODE_BLK(ino), offset, rdev);
316 break; 333 break;
317 } 334 }
335 case SQUASHFS_LBLKDEV_TYPE:
336 case SQUASHFS_LCHRDEV_TYPE: {
337 struct squashfs_ldev_inode *sqsh_ino = &squashfs_ino.ldev;
338 unsigned int rdev;
339
340 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
341 sizeof(*sqsh_ino));
342 if (err < 0)
343 goto failed_read;
344
345 if (type == SQUASHFS_LCHRDEV_TYPE)
346 inode->i_mode |= S_IFCHR;
347 else
348 inode->i_mode |= S_IFBLK;
349 xattr_id = le32_to_cpu(sqsh_ino->xattr);
350 inode->i_op = &squashfs_inode_ops;
351 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
352 rdev = le32_to_cpu(sqsh_ino->rdev);
353 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
354
355 TRACE("Device inode %x:%x, rdev %x\n",
356 SQUASHFS_INODE_BLK(ino), offset, rdev);
357 break;
358 }
318 case SQUASHFS_FIFO_TYPE: 359 case SQUASHFS_FIFO_TYPE:
319 case SQUASHFS_SOCKET_TYPE: 360 case SQUASHFS_SOCKET_TYPE: {
320 case SQUASHFS_LFIFO_TYPE:
321 case SQUASHFS_LSOCKET_TYPE: {
322 struct squashfs_ipc_inode *sqsh_ino = &squashfs_ino.ipc; 361 struct squashfs_ipc_inode *sqsh_ino = &squashfs_ino.ipc;
323 362
324 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 363 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
325 sizeof(*sqsh_ino)); 364 sizeof(*sqsh_ino));
326 if (err < 0) 365 if (err < 0)
327 goto failed_read; 366 goto failed_read;
328 367
329 if (type == SQUASHFS_FIFO_TYPE) 368 if (type == SQUASHFS_FIFO_TYPE)
330 inode->i_mode |= S_IFIFO; 369 inode->i_mode |= S_IFIFO;
331 else 370 else
332 inode->i_mode |= S_IFSOCK; 371 inode->i_mode |= S_IFSOCK;
333 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink); 372 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
334 init_special_inode(inode, inode->i_mode, 0); 373 init_special_inode(inode, inode->i_mode, 0);
335 break; 374 break;
336 } 375 }
376 case SQUASHFS_LFIFO_TYPE:
377 case SQUASHFS_LSOCKET_TYPE: {
378 struct squashfs_lipc_inode *sqsh_ino = &squashfs_ino.lipc;
379
380 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
381 sizeof(*sqsh_ino));
382 if (err < 0)
383 goto failed_read;
384
385 if (type == SQUASHFS_LFIFO_TYPE)
386 inode->i_mode |= S_IFIFO;
387 else
388 inode->i_mode |= S_IFSOCK;
389 xattr_id = le32_to_cpu(sqsh_ino->xattr);
390 inode->i_op = &squashfs_inode_ops;
391 inode->i_nlink = le32_to_cpu(sqsh_ino->nlink);
392 init_special_inode(inode, inode->i_mode, 0);
393 break;
394 }
337 default: 395 default:
338 ERROR("Unknown inode type %d in squashfs_iget!\n", type); 396 ERROR("Unknown inode type %d in squashfs_iget!\n", type);
339 return -EINVAL; 397 return -EINVAL;
340 } 398 }
341 399
400 if (xattr_id != SQUASHFS_INVALID_XATTR && msblk->xattr_id_table) {
401 err = squashfs_xattr_lookup(sb, xattr_id,
402 &squashfs_i(inode)->xattr_count,
403 &squashfs_i(inode)->xattr_size,
404 &squashfs_i(inode)->xattr);
405 if (err < 0)
406 goto failed_read;
407 inode->i_blocks += ((squashfs_i(inode)->xattr_size - 1) >> 9)
408 + 1;
409 } else
410 squashfs_i(inode)->xattr_count = 0;
411
342 return 0; 412 return 0;
343 413
344 failed_read: 414 failed_read:
345 ERROR("Unable to read inode 0x%llx\n", ino); 415 ERROR("Unable to read inode 0x%llx\n", ino);
346 return err; 416 return err;
347 } 417 }
418
419
420 const struct inode_operations squashfs_inode_ops = {
421 .getxattr = generic_getxattr,
1 /* 1 /*
2 * Squashfs - a compressed read only filesystem for Linux 2 * Squashfs - a compressed read only filesystem for Linux
3 * 3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@lougher.demon.co.uk> 5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2, 9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version. 10 * or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * 20 *
21 * namei.c 21 * namei.c
22 */ 22 */
23 23
24 /* 24 /*
25 * This file implements code to do filename lookup in directories. 25 * This file implements code to do filename lookup in directories.
26 * 26 *
27 * Like inodes, directories are packed into compressed metadata blocks, stored 27 * Like inodes, directories are packed into compressed metadata blocks, stored
28 * in a directory table. Directories are accessed using the start address of 28 * in a directory table. Directories are accessed using the start address of
29 * the metablock containing the directory and the offset into the 29 * the metablock containing the directory and the offset into the
30 * decompressed block (<block, offset>). 30 * decompressed block (<block, offset>).
31 * 31 *
32 * Directories are organised in a slightly complex way, and are not simply 32 * Directories are organised in a slightly complex way, and are not simply
33 * a list of file names. The organisation takes advantage of the 33 * a list of file names. The organisation takes advantage of the
34 * fact that (in most cases) the inodes of the files will be in the same 34 * fact that (in most cases) the inodes of the files will be in the same
35 * compressed metadata block, and therefore, can share the start block. 35 * compressed metadata block, and therefore, can share the start block.
36 * Directories are therefore organised in a two level list, a directory 36 * Directories are therefore organised in a two level list, a directory
37 * header containing the shared start block value, and a sequence of directory 37 * header containing the shared start block value, and a sequence of directory
38 * entries, each of which share the shared start block. A new directory header 38 * entries, each of which share the shared start block. A new directory header
39 * is written once/if the inode start block changes. The directory 39 * is written once/if the inode start block changes. The directory
40 * header/directory entry list is repeated as many times as necessary. 40 * header/directory entry list is repeated as many times as necessary.
41 * 41 *
42 * Directories are sorted, and can contain a directory index to speed up 42 * Directories are sorted, and can contain a directory index to speed up
43 * file lookup. Directory indexes store one entry per metablock, each entry 43 * file lookup. Directory indexes store one entry per metablock, each entry
44 * storing the index/filename mapping to the first directory header 44 * storing the index/filename mapping to the first directory header
45 * in each metadata block. Directories are sorted in alphabetical order, 45 * in each metadata block. Directories are sorted in alphabetical order,
46 * and at lookup the index is scanned linearly looking for the first filename 46 * and at lookup the index is scanned linearly looking for the first filename
47 * alphabetically larger than the filename being looked up. At this point the 47 * alphabetically larger than the filename being looked up. At this point the
48 * location of the metadata block the filename is in has been found. 48 * location of the metadata block the filename is in has been found.
49 * The general idea of the index is ensure only one metadata block needs to be 49 * The general idea of the index is ensure only one metadata block needs to be
50 * decompressed to do a lookup irrespective of the length of the directory. 50 * decompressed to do a lookup irrespective of the length of the directory.
51 * This scheme has the advantage that it doesn't require extra memory overhead 51 * This scheme has the advantage that it doesn't require extra memory overhead
52 * and doesn't require much extra storage on disk. 52 * and doesn't require much extra storage on disk.
53 */ 53 */
54 54
55 #include <linux/fs.h> 55 #include <linux/fs.h>
56 #include <linux/vfs.h> 56 #include <linux/vfs.h>
57 #include <linux/slab.h> 57 #include <linux/slab.h>
58 #include <linux/string.h> 58 #include <linux/string.h>
59 #include <linux/dcache.h> 59 #include <linux/dcache.h>
60 #include <linux/xattr.h>
60 61
61 #include "squashfs_fs.h" 62 #include "squashfs_fs.h"
62 #include "squashfs_fs_sb.h" 63 #include "squashfs_fs_sb.h"
63 #include "squashfs_fs_i.h" 64 #include "squashfs_fs_i.h"
64 #include "squashfs.h" 65 #include "squashfs.h"
65 66
66 /* 67 /*
67 * Lookup name in the directory index, returning the location of the metadata 68 * Lookup name in the directory index, returning the location of the metadata
68 * block containing it, and the directory index this represents. 69 * block containing it, and the directory index this represents.
69 * 70 *
70 * If we get an error reading the index then return the part of the index 71 * If we get an error reading the index then return the part of the index
71 * (if any) we have managed to read - the index isn't essential, just 72 * (if any) we have managed to read - the index isn't essential, just
72 * quicker. 73 * quicker.
73 */ 74 */
74 static int get_dir_index_using_name(struct super_block *sb, 75 static int get_dir_index_using_name(struct super_block *sb,
75 u64 *next_block, int *next_offset, u64 index_start, 76 u64 *next_block, int *next_offset, u64 index_start,
76 int index_offset, int i_count, const char *name, 77 int index_offset, int i_count, const char *name,
77 int len) 78 int len)
78 { 79 {
79 struct squashfs_sb_info *msblk = sb->s_fs_info; 80 struct squashfs_sb_info *msblk = sb->s_fs_info;
80 int i, size, length = 0, err; 81 int i, size, length = 0, err;
81 struct squashfs_dir_index *index; 82 struct squashfs_dir_index *index;
82 char *str; 83 char *str;
83 84
84 TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); 85 TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
85 86
86 index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN * 2 + 2, GFP_KERNEL); 87 index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN * 2 + 2, GFP_KERNEL);
87 if (index == NULL) { 88 if (index == NULL) {
88 ERROR("Failed to allocate squashfs_dir_index\n"); 89 ERROR("Failed to allocate squashfs_dir_index\n");
89 goto out; 90 goto out;
90 } 91 }
91 92
92 str = &index->name[SQUASHFS_NAME_LEN + 1]; 93 str = &index->name[SQUASHFS_NAME_LEN + 1];
93 strncpy(str, name, len); 94 strncpy(str, name, len);
94 str[len] = '\0'; 95 str[len] = '\0';
95 96
96 for (i = 0; i < i_count; i++) { 97 for (i = 0; i < i_count; i++) {
97 err = squashfs_read_metadata(sb, index, &index_start, 98 err = squashfs_read_metadata(sb, index, &index_start,
98 &index_offset, sizeof(*index)); 99 &index_offset, sizeof(*index));
99 if (err < 0) 100 if (err < 0)
100 break; 101 break;
101 102
102 103
103 size = le32_to_cpu(index->size) + 1; 104 size = le32_to_cpu(index->size) + 1;
104 105
105 err = squashfs_read_metadata(sb, index->name, &index_start, 106 err = squashfs_read_metadata(sb, index->name, &index_start,
106 &index_offset, size); 107 &index_offset, size);
107 if (err < 0) 108 if (err < 0)
108 break; 109 break;
109 110
110 index->name[size] = '\0'; 111 index->name[size] = '\0';
111 112
112 if (strcmp(index->name, str) > 0) 113 if (strcmp(index->name, str) > 0)
113 break; 114 break;
114 115
115 length = le32_to_cpu(index->index); 116 length = le32_to_cpu(index->index);
116 *next_block = le32_to_cpu(index->start_block) + 117 *next_block = le32_to_cpu(index->start_block) +
117 msblk->directory_table; 118 msblk->directory_table;
118 } 119 }
119 120
120 *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; 121 *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
121 kfree(index); 122 kfree(index);
122 123
123 out: 124 out:
124 /* 125 /*
125 * Return index (f_pos) of the looked up metadata block. Translate 126 * Return index (f_pos) of the looked up metadata block. Translate
126 * from internal f_pos to external f_pos which is offset by 3 because 127 * from internal f_pos to external f_pos which is offset by 3 because
127 * we invent "." and ".." entries which are not actually stored in the 128 * we invent "." and ".." entries which are not actually stored in the
128 * directory. 129 * directory.
129 */ 130 */
130 return length + 3; 131 return length + 3;
131 } 132 }
132 133
133 134
134 static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, 135 static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry,
135 struct nameidata *nd) 136 struct nameidata *nd)
136 { 137 {
137 const unsigned char *name = dentry->d_name.name; 138 const unsigned char *name = dentry->d_name.name;
138 int len = dentry->d_name.len; 139 int len = dentry->d_name.len;
139 struct inode *inode = NULL; 140 struct inode *inode = NULL;
140 struct squashfs_sb_info *msblk = dir->i_sb->s_fs_info; 141 struct squashfs_sb_info *msblk = dir->i_sb->s_fs_info;
141 struct squashfs_dir_header dirh; 142 struct squashfs_dir_header dirh;
142 struct squashfs_dir_entry *dire; 143 struct squashfs_dir_entry *dire;
143 u64 block = squashfs_i(dir)->start + msblk->directory_table; 144 u64 block = squashfs_i(dir)->start + msblk->directory_table;
144 int offset = squashfs_i(dir)->offset; 145 int offset = squashfs_i(dir)->offset;
145 int err, length = 0, dir_count, size; 146 int err, length = 0, dir_count, size;
146 147
147 TRACE("Entered squashfs_lookup [%llx:%x]\n", block, offset); 148 TRACE("Entered squashfs_lookup [%llx:%x]\n", block, offset);
148 149
149 dire = kmalloc(sizeof(*dire) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); 150 dire = kmalloc(sizeof(*dire) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
150 if (dire == NULL) { 151 if (dire == NULL) {
151 ERROR("Failed to allocate squashfs_dir_entry\n"); 152 ERROR("Failed to allocate squashfs_dir_entry\n");
152 return ERR_PTR(-ENOMEM); 153 return ERR_PTR(-ENOMEM);
153 } 154 }
154 155
155 if (len > SQUASHFS_NAME_LEN) { 156 if (len > SQUASHFS_NAME_LEN) {
156 err = -ENAMETOOLONG; 157 err = -ENAMETOOLONG;
157 goto failed; 158 goto failed;
158 } 159 }
159 160
160 length = get_dir_index_using_name(dir->i_sb, &block, &offset, 161 length = get_dir_index_using_name(dir->i_sb, &block, &offset,
161 squashfs_i(dir)->dir_idx_start, 162 squashfs_i(dir)->dir_idx_start,
162 squashfs_i(dir)->dir_idx_offset, 163 squashfs_i(dir)->dir_idx_offset,
163 squashfs_i(dir)->dir_idx_cnt, name, len); 164 squashfs_i(dir)->dir_idx_cnt, name, len);
164 165
165 while (length < i_size_read(dir)) { 166 while (length < i_size_read(dir)) {
166 /* 167 /*
167 * Read directory header. 168 * Read directory header.
168 */ 169 */
169 err = squashfs_read_metadata(dir->i_sb, &dirh, &block, 170 err = squashfs_read_metadata(dir->i_sb, &dirh, &block,
170 &offset, sizeof(dirh)); 171 &offset, sizeof(dirh));
171 if (err < 0) 172 if (err < 0)
172 goto read_failure; 173 goto read_failure;
173 174
174 length += sizeof(dirh); 175 length += sizeof(dirh);
175 176
176 dir_count = le32_to_cpu(dirh.count) + 1; 177 dir_count = le32_to_cpu(dirh.count) + 1;
177 while (dir_count--) { 178 while (dir_count--) {
178 /* 179 /*
179 * Read directory entry. 180 * Read directory entry.
180 */ 181 */
181 err = squashfs_read_metadata(dir->i_sb, dire, &block, 182 err = squashfs_read_metadata(dir->i_sb, dire, &block,
182 &offset, sizeof(*dire)); 183 &offset, sizeof(*dire));
183 if (err < 0) 184 if (err < 0)
184 goto read_failure; 185 goto read_failure;
185 186
186 size = le16_to_cpu(dire->size) + 1; 187 size = le16_to_cpu(dire->size) + 1;
187 188
188 err = squashfs_read_metadata(dir->i_sb, dire->name, 189 err = squashfs_read_metadata(dir->i_sb, dire->name,
189 &block, &offset, size); 190 &block, &offset, size);
190 if (err < 0) 191 if (err < 0)
191 goto read_failure; 192 goto read_failure;
192 193
193 length += sizeof(*dire) + size; 194 length += sizeof(*dire) + size;
194 195
195 if (name[0] < dire->name[0]) 196 if (name[0] < dire->name[0])
196 goto exit_lookup; 197 goto exit_lookup;
197 198
198 if (len == size && !strncmp(name, dire->name, len)) { 199 if (len == size && !strncmp(name, dire->name, len)) {
199 unsigned int blk, off, ino_num; 200 unsigned int blk, off, ino_num;
200 long long ino; 201 long long ino;
201 blk = le32_to_cpu(dirh.start_block); 202 blk = le32_to_cpu(dirh.start_block);
202 off = le16_to_cpu(dire->offset); 203 off = le16_to_cpu(dire->offset);
203 ino_num = le32_to_cpu(dirh.inode_number) + 204 ino_num = le32_to_cpu(dirh.inode_number) +
204 (short) le16_to_cpu(dire->inode_number); 205 (short) le16_to_cpu(dire->inode_number);
205 ino = SQUASHFS_MKINODE(blk, off); 206 ino = SQUASHFS_MKINODE(blk, off);
206 207
207 TRACE("calling squashfs_iget for directory " 208 TRACE("calling squashfs_iget for directory "
208 "entry %s, inode %x:%x, %d\n", name, 209 "entry %s, inode %x:%x, %d\n", name,
209 blk, off, ino_num); 210 blk, off, ino_num);
210 211
211 inode = squashfs_iget(dir->i_sb, ino, ino_num); 212 inode = squashfs_iget(dir->i_sb, ino, ino_num);
212 if (IS_ERR(inode)) { 213 if (IS_ERR(inode)) {
213 err = PTR_ERR(inode); 214 err = PTR_ERR(inode);
214 goto failed; 215 goto failed;
215 } 216 }
216 217
217 goto exit_lookup; 218 goto exit_lookup;
218 } 219 }
219 } 220 }
220 } 221 }
221 222
222 exit_lookup: 223 exit_lookup:
223 kfree(dire); 224 kfree(dire);
224 if (inode) 225 if (inode)
225 return d_splice_alias(inode, dentry); 226 return d_splice_alias(inode, dentry);
226 d_add(dentry, inode); 227 d_add(dentry, inode);
227 return ERR_PTR(0); 228 return ERR_PTR(0);
228 229
229 read_failure: 230 read_failure:
230 ERROR("Unable to read directory block [%llx:%x]\n", 231 ERROR("Unable to read directory block [%llx:%x]\n",
231 squashfs_i(dir)->start + msblk->directory_table, 232 squashfs_i(dir)->start + msblk->directory_table,
232 squashfs_i(dir)->offset); 233 squashfs_i(dir)->offset);
233 failed: 234 failed:
234 kfree(dire); 235 kfree(dire);
235 return ERR_PTR(err); 236 return ERR_PTR(err);
236 } 237 }
237 238
238 239
239 const struct inode_operations squashfs_dir_inode_ops = { 240 const struct inode_operations squashfs_dir_inode_ops = {
240 .lookup = squashfs_lookup 241 .lookup = squashfs_lookup,
242 .getxattr = generic_getxattr,
243 .listxattr = squashfs_listxattr
241 }; 244 };
242 245
fs/squashfs/squashfs.h
1 /* 1 /*
2 * Squashfs - a compressed read only filesystem for Linux 2 * Squashfs - a compressed read only filesystem for Linux
3 * 3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@lougher.demon.co.uk> 5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2, 9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version. 10 * or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * 20 *
21 * squashfs.h 21 * squashfs.h
22 */ 22 */
23 23
24 #define TRACE(s, args...) pr_debug("SQUASHFS: "s, ## args) 24 #define TRACE(s, args...) pr_debug("SQUASHFS: "s, ## args)
25 25
26 #define ERROR(s, args...) pr_err("SQUASHFS error: "s, ## args) 26 #define ERROR(s, args...) pr_err("SQUASHFS error: "s, ## args)
27 27
28 #define WARNING(s, args...) pr_warning("SQUASHFS: "s, ## args) 28 #define WARNING(s, args...) pr_warning("SQUASHFS: "s, ## args)
29 29
30 static inline struct squashfs_inode_info *squashfs_i(struct inode *inode) 30 static inline struct squashfs_inode_info *squashfs_i(struct inode *inode)
31 { 31 {
32 return list_entry(inode, struct squashfs_inode_info, vfs_inode); 32 return list_entry(inode, struct squashfs_inode_info, vfs_inode);
33 } 33 }
34 34
35 /* block.c */ 35 /* block.c */
36 extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *, 36 extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *,
37 int, int); 37 int, int);
38 38
39 /* cache.c */ 39 /* cache.c */
40 extern struct squashfs_cache *squashfs_cache_init(char *, int, int); 40 extern struct squashfs_cache *squashfs_cache_init(char *, int, int);
41 extern void squashfs_cache_delete(struct squashfs_cache *); 41 extern void squashfs_cache_delete(struct squashfs_cache *);
42 extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *, 42 extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *,
43 struct squashfs_cache *, u64, int); 43 struct squashfs_cache *, u64, int);
44 extern void squashfs_cache_put(struct squashfs_cache_entry *); 44 extern void squashfs_cache_put(struct squashfs_cache_entry *);
45 extern int squashfs_copy_data(void *, struct squashfs_cache_entry *, int, int); 45 extern int squashfs_copy_data(void *, struct squashfs_cache_entry *, int, int);
46 extern int squashfs_read_metadata(struct super_block *, void *, u64 *, 46 extern int squashfs_read_metadata(struct super_block *, void *, u64 *,
47 int *, int); 47 int *, int);
48 extern struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *, 48 extern struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *,
49 u64, int); 49 u64, int);
50 extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *, 50 extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *,
51 u64, int); 51 u64, int);
52 extern int squashfs_read_table(struct super_block *, void *, u64, int); 52 extern int squashfs_read_table(struct super_block *, void *, u64, int);
53 53
54 /* decompressor.c */ 54 /* decompressor.c */
55 extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); 55 extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
56 56
57 /* export.c */ 57 /* export.c */
58 extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, 58 extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64,
59 unsigned int); 59 unsigned int);
60 60
61 /* fragment.c */ 61 /* fragment.c */
62 extern int squashfs_frag_lookup(struct super_block *, unsigned int, u64 *); 62 extern int squashfs_frag_lookup(struct super_block *, unsigned int, u64 *);
63 extern __le64 *squashfs_read_fragment_index_table(struct super_block *, 63 extern __le64 *squashfs_read_fragment_index_table(struct super_block *,
64 u64, unsigned int); 64 u64, unsigned int);
65 65
66 /* id.c */ 66 /* id.c */
67 extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *); 67 extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *);
68 extern __le64 *squashfs_read_id_index_table(struct super_block *, u64, 68 extern __le64 *squashfs_read_id_index_table(struct super_block *, u64,
69 unsigned short); 69 unsigned short);
70 70
71 /* inode.c */ 71 /* inode.c */
72 extern struct inode *squashfs_iget(struct super_block *, long long, 72 extern struct inode *squashfs_iget(struct super_block *, long long,
73 unsigned int); 73 unsigned int);
74 extern int squashfs_read_inode(struct inode *, long long); 74 extern int squashfs_read_inode(struct inode *, long long);
75 75
76 /* xattr.c */
77 extern ssize_t squashfs_listxattr(struct dentry *, char *, size_t);
78
76 /* xattr_id.c */ 79 /* xattr_id.c */
77 extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, 80 extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
78 int *, long long *); 81 int *, long long *);
79 extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64, 82 extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
80 u64 *, int *); 83 u64 *, int *);
81 84
82 /* 85 /*
83 * Inodes, files and decompressor operations 86 * Inodes, files, decompressor and xattr operations
84 */ 87 */
85 88
86 /* dir.c */ 89 /* dir.c */
87 extern const struct file_operations squashfs_dir_ops; 90 extern const struct file_operations squashfs_dir_ops;
88 91
89 /* export.c */ 92 /* export.c */
90 extern const struct export_operations squashfs_export_ops; 93 extern const struct export_operations squashfs_export_ops;
91 94
92 /* file.c */ 95 /* file.c */
93 extern const struct address_space_operations squashfs_aops; 96 extern const struct address_space_operations squashfs_aops;
94 97
98 /* inode.c */
99 extern const struct inode_operations squashfs_inode_ops;
100
95 /* namei.c */ 101 /* namei.c */
96 extern const struct inode_operations squashfs_dir_inode_ops; 102 extern const struct inode_operations squashfs_dir_inode_ops;
97 103
98 /* symlink.c */ 104 /* symlink.c */
99 extern const struct address_space_operations squashfs_symlink_aops; 105 extern const struct address_space_operations squashfs_symlink_aops;
106 extern const struct inode_operations squashfs_symlink_inode_ops;
107
108 /* xattr.c */
109 extern struct xattr_handler *squashfs_xattr_handlers[];
100 110
101 /* zlib_wrapper.c */ 111 /* zlib_wrapper.c */
102 extern const struct squashfs_decompressor squashfs_zlib_comp_ops; 112 extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
103 113
fs/squashfs/squashfs_fs.h
1 #ifndef SQUASHFS_FS 1 #ifndef SQUASHFS_FS
2 #define SQUASHFS_FS 2 #define SQUASHFS_FS
3 /* 3 /*
4 * Squashfs 4 * Squashfs
5 * 5 *
6 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 6 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
7 * Phillip Lougher <phillip@lougher.demon.co.uk> 7 * Phillip Lougher <phillip@lougher.demon.co.uk>
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2, 11 * as published by the Free Software Foundation; either version 2,
12 * or (at your option) any later version. 12 * or (at your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details. 17 * GNU General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * 22 *
23 * squashfs_fs.h 23 * squashfs_fs.h
24 */ 24 */
25 25
26 #define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE 26 #define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
27 #define SQUASHFS_MAJOR 4 27 #define SQUASHFS_MAJOR 4
28 #define SQUASHFS_MINOR 0 28 #define SQUASHFS_MINOR 0
29 #define SQUASHFS_START 0 29 #define SQUASHFS_START 0
30 30
31 /* size of metadata (inode and directory) blocks */ 31 /* size of metadata (inode and directory) blocks */
32 #define SQUASHFS_METADATA_SIZE 8192 32 #define SQUASHFS_METADATA_SIZE 8192
33 #define SQUASHFS_METADATA_LOG 13 33 #define SQUASHFS_METADATA_LOG 13
34 34
35 /* default size of data blocks */ 35 /* default size of data blocks */
36 #define SQUASHFS_FILE_SIZE 131072 36 #define SQUASHFS_FILE_SIZE 131072
37 #define SQUASHFS_FILE_LOG 17 37 #define SQUASHFS_FILE_LOG 17
38 38
39 #define SQUASHFS_FILE_MAX_SIZE 1048576 39 #define SQUASHFS_FILE_MAX_SIZE 1048576
40 #define SQUASHFS_FILE_MAX_LOG 20 40 #define SQUASHFS_FILE_MAX_LOG 20
41 41
42 /* Max number of uids and gids */ 42 /* Max number of uids and gids */
43 #define SQUASHFS_IDS 65536 43 #define SQUASHFS_IDS 65536
44 44
45 /* Max length of filename (not 255) */ 45 /* Max length of filename (not 255) */
46 #define SQUASHFS_NAME_LEN 256 46 #define SQUASHFS_NAME_LEN 256
47 47
48 #define SQUASHFS_INVALID_FRAG (0xffffffffU) 48 #define SQUASHFS_INVALID_FRAG (0xffffffffU)
49 #define SQUASHFS_INVALID_XATTR (0xffffffffU) 49 #define SQUASHFS_INVALID_XATTR (0xffffffffU)
50 #define SQUASHFS_INVALID_BLK (-1LL) 50 #define SQUASHFS_INVALID_BLK (-1LL)
51 51
52 /* Filesystem flags */ 52 /* Filesystem flags */
53 #define SQUASHFS_NOI 0 53 #define SQUASHFS_NOI 0
54 #define SQUASHFS_NOD 1 54 #define SQUASHFS_NOD 1
55 #define SQUASHFS_NOF 3 55 #define SQUASHFS_NOF 3
56 #define SQUASHFS_NO_FRAG 4 56 #define SQUASHFS_NO_FRAG 4
57 #define SQUASHFS_ALWAYS_FRAG 5 57 #define SQUASHFS_ALWAYS_FRAG 5
58 #define SQUASHFS_DUPLICATE 6 58 #define SQUASHFS_DUPLICATE 6
59 #define SQUASHFS_EXPORT 7 59 #define SQUASHFS_EXPORT 7
60 60
61 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) 61 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
62 62
63 #define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ 63 #define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
64 SQUASHFS_NOI) 64 SQUASHFS_NOI)
65 65
66 #define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ 66 #define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
67 SQUASHFS_NOD) 67 SQUASHFS_NOD)
68 68
69 #define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ 69 #define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
70 SQUASHFS_NOF) 70 SQUASHFS_NOF)
71 71
72 #define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ 72 #define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
73 SQUASHFS_NO_FRAG) 73 SQUASHFS_NO_FRAG)
74 74
75 #define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ 75 #define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
76 SQUASHFS_ALWAYS_FRAG) 76 SQUASHFS_ALWAYS_FRAG)
77 77
78 #define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ 78 #define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
79 SQUASHFS_DUPLICATE) 79 SQUASHFS_DUPLICATE)
80 80
81 #define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ 81 #define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
82 SQUASHFS_EXPORT) 82 SQUASHFS_EXPORT)
83 83
84 /* Max number of types and file types */ 84 /* Max number of types and file types */
85 #define SQUASHFS_DIR_TYPE 1 85 #define SQUASHFS_DIR_TYPE 1
86 #define SQUASHFS_REG_TYPE 2 86 #define SQUASHFS_REG_TYPE 2
87 #define SQUASHFS_SYMLINK_TYPE 3 87 #define SQUASHFS_SYMLINK_TYPE 3
88 #define SQUASHFS_BLKDEV_TYPE 4 88 #define SQUASHFS_BLKDEV_TYPE 4
89 #define SQUASHFS_CHRDEV_TYPE 5 89 #define SQUASHFS_CHRDEV_TYPE 5
90 #define SQUASHFS_FIFO_TYPE 6 90 #define SQUASHFS_FIFO_TYPE 6
91 #define SQUASHFS_SOCKET_TYPE 7 91 #define SQUASHFS_SOCKET_TYPE 7
92 #define SQUASHFS_LDIR_TYPE 8 92 #define SQUASHFS_LDIR_TYPE 8
93 #define SQUASHFS_LREG_TYPE 9 93 #define SQUASHFS_LREG_TYPE 9
94 #define SQUASHFS_LSYMLINK_TYPE 10 94 #define SQUASHFS_LSYMLINK_TYPE 10
95 #define SQUASHFS_LBLKDEV_TYPE 11 95 #define SQUASHFS_LBLKDEV_TYPE 11
96 #define SQUASHFS_LCHRDEV_TYPE 12 96 #define SQUASHFS_LCHRDEV_TYPE 12
97 #define SQUASHFS_LFIFO_TYPE 13 97 #define SQUASHFS_LFIFO_TYPE 13
98 #define SQUASHFS_LSOCKET_TYPE 14 98 #define SQUASHFS_LSOCKET_TYPE 14
99 99
100 /* Xattr types */ 100 /* Xattr types */
101 #define SQUASHFS_XATTR_USER 0 101 #define SQUASHFS_XATTR_USER 0
102 #define SQUASHFS_XATTR_TRUSTED 1 102 #define SQUASHFS_XATTR_TRUSTED 1
103 #define SQUASHFS_XATTR_SECURITY 2 103 #define SQUASHFS_XATTR_SECURITY 2
104 #define SQUASHFS_XATTR_VALUE_OOL 256 104 #define SQUASHFS_XATTR_VALUE_OOL 256
105 #define SQUASHFS_XATTR_PREFIX_MASK 0xff 105 #define SQUASHFS_XATTR_PREFIX_MASK 0xff
106 106
107 /* Flag whether block is compressed or uncompressed, bit is set if block is 107 /* Flag whether block is compressed or uncompressed, bit is set if block is
108 * uncompressed */ 108 * uncompressed */
109 #define SQUASHFS_COMPRESSED_BIT (1 << 15) 109 #define SQUASHFS_COMPRESSED_BIT (1 << 15)
110 110
111 #define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ 111 #define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
112 (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) 112 (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
113 113
114 #define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) 114 #define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
115 115
116 #define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) 116 #define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
117 117
118 #define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \ 118 #define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \
119 ~SQUASHFS_COMPRESSED_BIT_BLOCK) 119 ~SQUASHFS_COMPRESSED_BIT_BLOCK)
120 120
121 #define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) 121 #define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
122 122
123 /* 123 /*
124 * Inode number ops. Inodes consist of a compressed block number, and an 124 * Inode number ops. Inodes consist of a compressed block number, and an
125 * uncompressed offset within that block 125 * uncompressed offset within that block
126 */ 126 */
127 #define SQUASHFS_INODE_BLK(A) ((unsigned int) ((A) >> 16)) 127 #define SQUASHFS_INODE_BLK(A) ((unsigned int) ((A) >> 16))
128 128
129 #define SQUASHFS_INODE_OFFSET(A) ((unsigned int) ((A) & 0xffff)) 129 #define SQUASHFS_INODE_OFFSET(A) ((unsigned int) ((A) & 0xffff))
130 130
131 #define SQUASHFS_MKINODE(A, B) ((long long)(((long long) (A)\ 131 #define SQUASHFS_MKINODE(A, B) ((long long)(((long long) (A)\
132 << 16) + (B))) 132 << 16) + (B)))
133 133
134 /* Translate between VFS mode and squashfs mode */ 134 /* Translate between VFS mode and squashfs mode */
135 #define SQUASHFS_MODE(A) ((A) & 0xfff) 135 #define SQUASHFS_MODE(A) ((A) & 0xfff)
136 136
137 /* fragment and fragment table defines */ 137 /* fragment and fragment table defines */
138 #define SQUASHFS_FRAGMENT_BYTES(A) \ 138 #define SQUASHFS_FRAGMENT_BYTES(A) \
139 ((A) * sizeof(struct squashfs_fragment_entry)) 139 ((A) * sizeof(struct squashfs_fragment_entry))
140 140
141 #define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ 141 #define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
142 SQUASHFS_METADATA_SIZE) 142 SQUASHFS_METADATA_SIZE)
143 143
144 #define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ 144 #define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
145 SQUASHFS_METADATA_SIZE) 145 SQUASHFS_METADATA_SIZE)
146 146
147 #define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ 147 #define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
148 SQUASHFS_METADATA_SIZE - 1) / \ 148 SQUASHFS_METADATA_SIZE - 1) / \
149 SQUASHFS_METADATA_SIZE) 149 SQUASHFS_METADATA_SIZE)
150 150
151 #define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ 151 #define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
152 sizeof(u64)) 152 sizeof(u64))
153 153
154 /* inode lookup table defines */ 154 /* inode lookup table defines */
155 #define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(u64)) 155 #define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(u64))
156 156
157 #define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \ 157 #define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
158 SQUASHFS_METADATA_SIZE) 158 SQUASHFS_METADATA_SIZE)
159 159
160 #define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \ 160 #define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
161 SQUASHFS_METADATA_SIZE) 161 SQUASHFS_METADATA_SIZE)
162 162
163 #define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \ 163 #define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
164 SQUASHFS_METADATA_SIZE - 1) / \ 164 SQUASHFS_METADATA_SIZE - 1) / \
165 SQUASHFS_METADATA_SIZE) 165 SQUASHFS_METADATA_SIZE)
166 166
167 #define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\ 167 #define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
168 sizeof(u64)) 168 sizeof(u64))
169 169
170 /* uid/gid lookup table defines */ 170 /* uid/gid lookup table defines */
171 #define SQUASHFS_ID_BYTES(A) ((A) * sizeof(unsigned int)) 171 #define SQUASHFS_ID_BYTES(A) ((A) * sizeof(unsigned int))
172 172
173 #define SQUASHFS_ID_BLOCK(A) (SQUASHFS_ID_BYTES(A) / \ 173 #define SQUASHFS_ID_BLOCK(A) (SQUASHFS_ID_BYTES(A) / \
174 SQUASHFS_METADATA_SIZE) 174 SQUASHFS_METADATA_SIZE)
175 175
176 #define SQUASHFS_ID_BLOCK_OFFSET(A) (SQUASHFS_ID_BYTES(A) % \ 176 #define SQUASHFS_ID_BLOCK_OFFSET(A) (SQUASHFS_ID_BYTES(A) % \
177 SQUASHFS_METADATA_SIZE) 177 SQUASHFS_METADATA_SIZE)
178 178
179 #define SQUASHFS_ID_BLOCKS(A) ((SQUASHFS_ID_BYTES(A) + \ 179 #define SQUASHFS_ID_BLOCKS(A) ((SQUASHFS_ID_BYTES(A) + \
180 SQUASHFS_METADATA_SIZE - 1) / \ 180 SQUASHFS_METADATA_SIZE - 1) / \
181 SQUASHFS_METADATA_SIZE) 181 SQUASHFS_METADATA_SIZE)
182 182
183 #define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\ 183 #define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\
184 sizeof(u64)) 184 sizeof(u64))
185 /* xattr id lookup table defines */ 185 /* xattr id lookup table defines */
186 #define SQUASHFS_XATTR_BYTES(A) ((A) * sizeof(struct squashfs_xattr_id)) 186 #define SQUASHFS_XATTR_BYTES(A) ((A) * sizeof(struct squashfs_xattr_id))
187 187
188 #define SQUASHFS_XATTR_BLOCK(A) (SQUASHFS_XATTR_BYTES(A) / \ 188 #define SQUASHFS_XATTR_BLOCK(A) (SQUASHFS_XATTR_BYTES(A) / \
189 SQUASHFS_METADATA_SIZE) 189 SQUASHFS_METADATA_SIZE)
190 190
191 #define SQUASHFS_XATTR_BLOCK_OFFSET(A) (SQUASHFS_XATTR_BYTES(A) % \ 191 #define SQUASHFS_XATTR_BLOCK_OFFSET(A) (SQUASHFS_XATTR_BYTES(A) % \
192 SQUASHFS_METADATA_SIZE) 192 SQUASHFS_METADATA_SIZE)
193 193
194 #define SQUASHFS_XATTR_BLOCKS(A) ((SQUASHFS_XATTR_BYTES(A) + \ 194 #define SQUASHFS_XATTR_BLOCKS(A) ((SQUASHFS_XATTR_BYTES(A) + \
195 SQUASHFS_METADATA_SIZE - 1) / \ 195 SQUASHFS_METADATA_SIZE - 1) / \
196 SQUASHFS_METADATA_SIZE) 196 SQUASHFS_METADATA_SIZE)
197 197
198 #define SQUASHFS_XATTR_BLOCK_BYTES(A) (SQUASHFS_XATTR_BLOCKS(A) *\ 198 #define SQUASHFS_XATTR_BLOCK_BYTES(A) (SQUASHFS_XATTR_BLOCKS(A) *\
199 sizeof(u64)) 199 sizeof(u64))
200 #define SQUASHFS_XATTR_BLK(A) ((unsigned int) ((A) >> 16)) 200 #define SQUASHFS_XATTR_BLK(A) ((unsigned int) ((A) >> 16))
201 201
202 #define SQUASHFS_XATTR_OFFSET(A) ((unsigned int) ((A) & 0xffff)) 202 #define SQUASHFS_XATTR_OFFSET(A) ((unsigned int) ((A) & 0xffff))
203 203
204 /* cached data constants for filesystem */ 204 /* cached data constants for filesystem */
205 #define SQUASHFS_CACHED_BLKS 8 205 #define SQUASHFS_CACHED_BLKS 8
206 206
207 #define SQUASHFS_MAX_FILE_SIZE_LOG 64 207 #define SQUASHFS_MAX_FILE_SIZE_LOG 64
208 208
209 #define SQUASHFS_MAX_FILE_SIZE (1LL << \ 209 #define SQUASHFS_MAX_FILE_SIZE (1LL << \
210 (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) 210 (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
211 211
212 /* meta index cache */ 212 /* meta index cache */
213 #define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) 213 #define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
214 #define SQUASHFS_META_ENTRIES 127 214 #define SQUASHFS_META_ENTRIES 127
215 #define SQUASHFS_META_SLOTS 8 215 #define SQUASHFS_META_SLOTS 8
216 216
217 struct meta_entry { 217 struct meta_entry {
218 u64 data_block; 218 u64 data_block;
219 unsigned int index_block; 219 unsigned int index_block;
220 unsigned short offset; 220 unsigned short offset;
221 unsigned short pad; 221 unsigned short pad;
222 }; 222 };
223 223
224 struct meta_index { 224 struct meta_index {
225 unsigned int inode_number; 225 unsigned int inode_number;
226 unsigned int offset; 226 unsigned int offset;
227 unsigned short entries; 227 unsigned short entries;
228 unsigned short skip; 228 unsigned short skip;
229 unsigned short locked; 229 unsigned short locked;
230 unsigned short pad; 230 unsigned short pad;
231 struct meta_entry meta_entry[SQUASHFS_META_ENTRIES]; 231 struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
232 }; 232 };
233 233
234 234
235 /* 235 /*
236 * definitions for structures on disk 236 * definitions for structures on disk
237 */ 237 */
238 #define ZLIB_COMPRESSION 1 238 #define ZLIB_COMPRESSION 1
239 #define LZMA_COMPRESSION 2 239 #define LZMA_COMPRESSION 2
240 #define LZO_COMPRESSION 3 240 #define LZO_COMPRESSION 3
241 241
242 struct squashfs_super_block { 242 struct squashfs_super_block {
243 __le32 s_magic; 243 __le32 s_magic;
244 __le32 inodes; 244 __le32 inodes;
245 __le32 mkfs_time; 245 __le32 mkfs_time;
246 __le32 block_size; 246 __le32 block_size;
247 __le32 fragments; 247 __le32 fragments;
248 __le16 compression; 248 __le16 compression;
249 __le16 block_log; 249 __le16 block_log;
250 __le16 flags; 250 __le16 flags;
251 __le16 no_ids; 251 __le16 no_ids;
252 __le16 s_major; 252 __le16 s_major;
253 __le16 s_minor; 253 __le16 s_minor;
254 __le64 root_inode; 254 __le64 root_inode;
255 __le64 bytes_used; 255 __le64 bytes_used;
256 __le64 id_table_start; 256 __le64 id_table_start;
257 __le64 xattr_id_table_start; 257 __le64 xattr_id_table_start;
258 __le64 inode_table_start; 258 __le64 inode_table_start;
259 __le64 directory_table_start; 259 __le64 directory_table_start;
260 __le64 fragment_table_start; 260 __le64 fragment_table_start;
261 __le64 lookup_table_start; 261 __le64 lookup_table_start;
262 }; 262 };
263 263
264 struct squashfs_dir_index { 264 struct squashfs_dir_index {
265 __le32 index; 265 __le32 index;
266 __le32 start_block; 266 __le32 start_block;
267 __le32 size; 267 __le32 size;
268 unsigned char name[0]; 268 unsigned char name[0];
269 }; 269 };
270 270
271 struct squashfs_base_inode { 271 struct squashfs_base_inode {
272 __le16 inode_type; 272 __le16 inode_type;
273 __le16 mode; 273 __le16 mode;
274 __le16 uid; 274 __le16 uid;
275 __le16 guid; 275 __le16 guid;
276 __le32 mtime; 276 __le32 mtime;
277 __le32 inode_number; 277 __le32 inode_number;
278 }; 278 };
279 279
280 struct squashfs_ipc_inode { 280 struct squashfs_ipc_inode {
281 __le16 inode_type; 281 __le16 inode_type;
282 __le16 mode; 282 __le16 mode;
283 __le16 uid; 283 __le16 uid;
284 __le16 guid; 284 __le16 guid;
285 __le32 mtime; 285 __le32 mtime;
286 __le32 inode_number; 286 __le32 inode_number;
287 __le32 nlink; 287 __le32 nlink;
288 }; 288 };
289 289
290 struct squashfs_lipc_inode {
291 __le16 inode_type;
292 __le16 mode;
293 __le16 uid;
294 __le16 guid;
295 __le32 mtime;
296 __le32 inode_number;
297 __le32 nlink;
298 __le32 xattr;
299 };
300
290 struct squashfs_dev_inode { 301 struct squashfs_dev_inode {
291 __le16 inode_type; 302 __le16 inode_type;
292 __le16 mode; 303 __le16 mode;
293 __le16 uid; 304 __le16 uid;
294 __le16 guid; 305 __le16 guid;
295 __le32 mtime; 306 __le32 mtime;
296 __le32 inode_number; 307 __le32 inode_number;
297 __le32 nlink; 308 __le32 nlink;
298 __le32 rdev; 309 __le32 rdev;
299 }; 310 };
300 311
312 struct squashfs_ldev_inode {
313 __le16 inode_type;
314 __le16 mode;
315 __le16 uid;
316 __le16 guid;
317 __le32 mtime;
318 __le32 inode_number;
319 __le32 nlink;
320 __le32 rdev;
321 __le32 xattr;
322 };
323
301 struct squashfs_symlink_inode { 324 struct squashfs_symlink_inode {
302 __le16 inode_type; 325 __le16 inode_type;
303 __le16 mode; 326 __le16 mode;
304 __le16 uid; 327 __le16 uid;
305 __le16 guid; 328 __le16 guid;
306 __le32 mtime; 329 __le32 mtime;
307 __le32 inode_number; 330 __le32 inode_number;
308 __le32 nlink; 331 __le32 nlink;
309 __le32 symlink_size; 332 __le32 symlink_size;
310 char symlink[0]; 333 char symlink[0];
311 }; 334 };
312 335
313 struct squashfs_reg_inode { 336 struct squashfs_reg_inode {
314 __le16 inode_type; 337 __le16 inode_type;
315 __le16 mode; 338 __le16 mode;
316 __le16 uid; 339 __le16 uid;
317 __le16 guid; 340 __le16 guid;
318 __le32 mtime; 341 __le32 mtime;
319 __le32 inode_number; 342 __le32 inode_number;
320 __le32 start_block; 343 __le32 start_block;
321 __le32 fragment; 344 __le32 fragment;
322 __le32 offset; 345 __le32 offset;
323 __le32 file_size; 346 __le32 file_size;
324 __le16 block_list[0]; 347 __le16 block_list[0];
325 }; 348 };
326 349
327 struct squashfs_lreg_inode { 350 struct squashfs_lreg_inode {
328 __le16 inode_type; 351 __le16 inode_type;
329 __le16 mode; 352 __le16 mode;
330 __le16 uid; 353 __le16 uid;
331 __le16 guid; 354 __le16 guid;
332 __le32 mtime; 355 __le32 mtime;
333 __le32 inode_number; 356 __le32 inode_number;
334 __le64 start_block; 357 __le64 start_block;
335 __le64 file_size; 358 __le64 file_size;
336 __le64 sparse; 359 __le64 sparse;
337 __le32 nlink; 360 __le32 nlink;
338 __le32 fragment; 361 __le32 fragment;
339 __le32 offset; 362 __le32 offset;
340 __le32 xattr; 363 __le32 xattr;
341 __le16 block_list[0]; 364 __le16 block_list[0];
342 }; 365 };
343 366
344 struct squashfs_dir_inode { 367 struct squashfs_dir_inode {
345 __le16 inode_type; 368 __le16 inode_type;
346 __le16 mode; 369 __le16 mode;
347 __le16 uid; 370 __le16 uid;
348 __le16 guid; 371 __le16 guid;
349 __le32 mtime; 372 __le32 mtime;
350 __le32 inode_number; 373 __le32 inode_number;
351 __le32 start_block; 374 __le32 start_block;
352 __le32 nlink; 375 __le32 nlink;
353 __le16 file_size; 376 __le16 file_size;
354 __le16 offset; 377 __le16 offset;
355 __le32 parent_inode; 378 __le32 parent_inode;
356 }; 379 };
357 380
358 struct squashfs_ldir_inode { 381 struct squashfs_ldir_inode {
359 __le16 inode_type; 382 __le16 inode_type;
360 __le16 mode; 383 __le16 mode;
361 __le16 uid; 384 __le16 uid;
362 __le16 guid; 385 __le16 guid;
363 __le32 mtime; 386 __le32 mtime;
364 __le32 inode_number; 387 __le32 inode_number;
365 __le32 nlink; 388 __le32 nlink;
366 __le32 file_size; 389 __le32 file_size;
367 __le32 start_block; 390 __le32 start_block;
368 __le32 parent_inode; 391 __le32 parent_inode;
369 __le16 i_count; 392 __le16 i_count;
370 __le16 offset; 393 __le16 offset;
371 __le32 xattr; 394 __le32 xattr;
372 struct squashfs_dir_index index[0]; 395 struct squashfs_dir_index index[0];
373 }; 396 };
374 397
375 union squashfs_inode { 398 union squashfs_inode {
376 struct squashfs_base_inode base; 399 struct squashfs_base_inode base;
377 struct squashfs_dev_inode dev; 400 struct squashfs_dev_inode dev;
401 struct squashfs_ldev_inode ldev;
378 struct squashfs_symlink_inode symlink; 402 struct squashfs_symlink_inode symlink;
379 struct squashfs_reg_inode reg; 403 struct squashfs_reg_inode reg;
380 struct squashfs_lreg_inode lreg; 404 struct squashfs_lreg_inode lreg;
381 struct squashfs_dir_inode dir; 405 struct squashfs_dir_inode dir;
382 struct squashfs_ldir_inode ldir; 406 struct squashfs_ldir_inode ldir;
383 struct squashfs_ipc_inode ipc; 407 struct squashfs_ipc_inode ipc;
408 struct squashfs_lipc_inode lipc;
384 }; 409 };
385 410
386 struct squashfs_dir_entry { 411 struct squashfs_dir_entry {
387 __le16 offset; 412 __le16 offset;
388 __le16 inode_number; 413 __le16 inode_number;
389 __le16 type; 414 __le16 type;
390 __le16 size; 415 __le16 size;
391 char name[0]; 416 char name[0];
392 }; 417 };
393 418
394 struct squashfs_dir_header { 419 struct squashfs_dir_header {
395 __le32 count; 420 __le32 count;
396 __le32 start_block; 421 __le32 start_block;
397 __le32 inode_number; 422 __le32 inode_number;
398 }; 423 };
399 424
400 struct squashfs_fragment_entry { 425 struct squashfs_fragment_entry {
401 __le64 start_block; 426 __le64 start_block;
402 __le32 size; 427 __le32 size;
403 unsigned int unused; 428 unsigned int unused;
404 }; 429 };
405 430
406 struct squashfs_xattr_entry { 431 struct squashfs_xattr_entry {
407 __le16 type; 432 __le16 type;
408 __le16 size; 433 __le16 size;
409 char data[0]; 434 char data[0];
410 }; 435 };
411 436
412 struct squashfs_xattr_val { 437 struct squashfs_xattr_val {
413 __le32 vsize; 438 __le32 vsize;
414 char value[0]; 439 char value[0];
415 }; 440 };
416 441
417 struct squashfs_xattr_id { 442 struct squashfs_xattr_id {
418 __le64 xattr; 443 __le64 xattr;
419 __le32 count; 444 __le32 count;
420 __le32 size; 445 __le32 size;
421 }; 446 };
422 447
423 struct squashfs_xattr_id_table { 448 struct squashfs_xattr_id_table {
424 __le64 xattr_table_start; 449 __le64 xattr_table_start;
425 __le32 xattr_ids; 450 __le32 xattr_ids;
426 __le32 unused; 451 __le32 unused;
427 }; 452 };
428 453
429 #endif 454 #endif
430 455
1 /* 1 /*
2 * Squashfs - a compressed read only filesystem for Linux 2 * Squashfs - a compressed read only filesystem for Linux
3 * 3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@lougher.demon.co.uk> 5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2, 9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version. 10 * or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * 20 *
21 * super.c 21 * super.c
22 */ 22 */
23 23
24 /* 24 /*
25 * This file implements code to read the superblock, read and initialise 25 * This file implements code to read the superblock, read and initialise
26 * in-memory structures at mount time, and all the VFS glue code to register 26 * in-memory structures at mount time, and all the VFS glue code to register
27 * the filesystem. 27 * the filesystem.
28 */ 28 */
29 29
30 #include <linux/fs.h> 30 #include <linux/fs.h>
31 #include <linux/vfs.h> 31 #include <linux/vfs.h>
32 #include <linux/slab.h> 32 #include <linux/slab.h>
33 #include <linux/smp_lock.h> 33 #include <linux/smp_lock.h>
34 #include <linux/mutex.h> 34 #include <linux/mutex.h>
35 #include <linux/pagemap.h> 35 #include <linux/pagemap.h>
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 #include <linux/xattr.h>
40 40
41 #include "squashfs_fs.h" 41 #include "squashfs_fs.h"
42 #include "squashfs_fs_sb.h" 42 #include "squashfs_fs_sb.h"
43 #include "squashfs_fs_i.h" 43 #include "squashfs_fs_i.h"
44 #include "squashfs.h" 44 #include "squashfs.h"
45 #include "decompressor.h" 45 #include "decompressor.h"
46 46
47 static struct file_system_type squashfs_fs_type; 47 static struct file_system_type squashfs_fs_type;
48 static const struct super_operations squashfs_super_ops; 48 static const struct super_operations squashfs_super_ops;
49 49
50 static const struct squashfs_decompressor *supported_squashfs_filesystem(short 50 static const struct squashfs_decompressor *supported_squashfs_filesystem(short
51 major, short minor, short id) 51 major, short minor, short id)
52 { 52 {
53 const struct squashfs_decompressor *decompressor; 53 const struct squashfs_decompressor *decompressor;
54 54
55 if (major < SQUASHFS_MAJOR) { 55 if (major < SQUASHFS_MAJOR) {
56 ERROR("Major/Minor mismatch, older Squashfs %d.%d " 56 ERROR("Major/Minor mismatch, older Squashfs %d.%d "
57 "filesystems are unsupported\n", major, minor); 57 "filesystems are unsupported\n", major, minor);
58 return NULL; 58 return NULL;
59 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { 59 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
60 ERROR("Major/Minor mismatch, trying to mount newer " 60 ERROR("Major/Minor mismatch, trying to mount newer "
61 "%d.%d filesystem\n", major, minor); 61 "%d.%d filesystem\n", major, minor);
62 ERROR("Please update your kernel\n"); 62 ERROR("Please update your kernel\n");
63 return NULL; 63 return NULL;
64 } 64 }
65 65
66 decompressor = squashfs_lookup_decompressor(id); 66 decompressor = squashfs_lookup_decompressor(id);
67 if (!decompressor->supported) { 67 if (!decompressor->supported) {
68 ERROR("Filesystem uses \"%s\" compression. This is not " 68 ERROR("Filesystem uses \"%s\" compression. This is not "
69 "supported\n", decompressor->name); 69 "supported\n", decompressor->name);
70 return NULL; 70 return NULL;
71 } 71 }
72 72
73 return decompressor; 73 return decompressor;
74 } 74 }
75 75
76 76
77 static int squashfs_fill_super(struct super_block *sb, void *data, int silent) 77 static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
78 { 78 {
79 struct squashfs_sb_info *msblk; 79 struct squashfs_sb_info *msblk;
80 struct squashfs_super_block *sblk = NULL; 80 struct squashfs_super_block *sblk = NULL;
81 char b[BDEVNAME_SIZE]; 81 char b[BDEVNAME_SIZE];
82 struct inode *root; 82 struct inode *root;
83 long long root_inode; 83 long long root_inode;
84 unsigned short flags; 84 unsigned short flags;
85 unsigned int fragments; 85 unsigned int fragments;
86 u64 lookup_table_start, xattr_id_table_start; 86 u64 lookup_table_start, xattr_id_table_start;
87 int err; 87 int err;
88 88
89 TRACE("Entered squashfs_fill_superblock\n"); 89 TRACE("Entered squashfs_fill_superblock\n");
90 90
91 sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); 91 sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
92 if (sb->s_fs_info == NULL) { 92 if (sb->s_fs_info == NULL) {
93 ERROR("Failed to allocate squashfs_sb_info\n"); 93 ERROR("Failed to allocate squashfs_sb_info\n");
94 return -ENOMEM; 94 return -ENOMEM;
95 } 95 }
96 msblk = sb->s_fs_info; 96 msblk = sb->s_fs_info;
97 97
98 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); 98 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
99 if (sblk == NULL) { 99 if (sblk == NULL) {
100 ERROR("Failed to allocate squashfs_super_block\n"); 100 ERROR("Failed to allocate squashfs_super_block\n");
101 goto failure; 101 goto failure;
102 } 102 }
103 103
104 msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE); 104 msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE);
105 msblk->devblksize_log2 = ffz(~msblk->devblksize); 105 msblk->devblksize_log2 = ffz(~msblk->devblksize);
106 106
107 mutex_init(&msblk->read_data_mutex); 107 mutex_init(&msblk->read_data_mutex);
108 mutex_init(&msblk->meta_index_mutex); 108 mutex_init(&msblk->meta_index_mutex);
109 109
110 /* 110 /*
111 * msblk->bytes_used is checked in squashfs_read_table to ensure reads 111 * msblk->bytes_used is checked in squashfs_read_table to ensure reads
112 * are not beyond filesystem end. But as we're using 112 * are not beyond filesystem end. But as we're using
113 * squashfs_read_table here to read the superblock (including the value 113 * squashfs_read_table here to read the superblock (including the value
114 * of bytes_used) we need to set it to an initial sensible dummy value 114 * of bytes_used) we need to set it to an initial sensible dummy value
115 */ 115 */
116 msblk->bytes_used = sizeof(*sblk); 116 msblk->bytes_used = sizeof(*sblk);
117 err = squashfs_read_table(sb, sblk, SQUASHFS_START, sizeof(*sblk)); 117 err = squashfs_read_table(sb, sblk, SQUASHFS_START, sizeof(*sblk));
118 118
119 if (err < 0) { 119 if (err < 0) {
120 ERROR("unable to read squashfs_super_block\n"); 120 ERROR("unable to read squashfs_super_block\n");
121 goto failed_mount; 121 goto failed_mount;
122 } 122 }
123 123
124 err = -EINVAL; 124 err = -EINVAL;
125 125
126 /* Check it is a SQUASHFS superblock */ 126 /* Check it is a SQUASHFS superblock */
127 sb->s_magic = le32_to_cpu(sblk->s_magic); 127 sb->s_magic = le32_to_cpu(sblk->s_magic);
128 if (sb->s_magic != SQUASHFS_MAGIC) { 128 if (sb->s_magic != SQUASHFS_MAGIC) {
129 if (!silent) 129 if (!silent)
130 ERROR("Can't find a SQUASHFS superblock on %s\n", 130 ERROR("Can't find a SQUASHFS superblock on %s\n",
131 bdevname(sb->s_bdev, b)); 131 bdevname(sb->s_bdev, b));
132 goto failed_mount; 132 goto failed_mount;
133 } 133 }
134 134
135 /* Check the MAJOR & MINOR versions and lookup compression type */ 135 /* Check the MAJOR & MINOR versions and lookup compression type */
136 msblk->decompressor = supported_squashfs_filesystem( 136 msblk->decompressor = supported_squashfs_filesystem(
137 le16_to_cpu(sblk->s_major), 137 le16_to_cpu(sblk->s_major),
138 le16_to_cpu(sblk->s_minor), 138 le16_to_cpu(sblk->s_minor),
139 le16_to_cpu(sblk->compression)); 139 le16_to_cpu(sblk->compression));
140 if (msblk->decompressor == NULL) 140 if (msblk->decompressor == NULL)
141 goto failed_mount; 141 goto failed_mount;
142 142
143 /*
144 * Check if there's xattrs in the filesystem. These are not
145 * supported in this version, so warn that they will be ignored.
146 */
147 if (le64_to_cpu(sblk->xattr_id_table_start) != SQUASHFS_INVALID_BLK)
148 ERROR("Xattrs in filesystem, these will be ignored\n");
149
150 /* Check the filesystem does not extend beyond the end of the 143 /* Check the filesystem does not extend beyond the end of the
151 block device */ 144 block device */
152 msblk->bytes_used = le64_to_cpu(sblk->bytes_used); 145 msblk->bytes_used = le64_to_cpu(sblk->bytes_used);
153 if (msblk->bytes_used < 0 || msblk->bytes_used > 146 if (msblk->bytes_used < 0 || msblk->bytes_used >
154 i_size_read(sb->s_bdev->bd_inode)) 147 i_size_read(sb->s_bdev->bd_inode))
155 goto failed_mount; 148 goto failed_mount;
156 149
157 /* Check block size for sanity */ 150 /* Check block size for sanity */
158 msblk->block_size = le32_to_cpu(sblk->block_size); 151 msblk->block_size = le32_to_cpu(sblk->block_size);
159 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE) 152 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
160 goto failed_mount; 153 goto failed_mount;
161 154
162 /* 155 /*
163 * Check the system page size is not larger than the filesystem 156 * Check the system page size is not larger than the filesystem
164 * block size (by default 128K). This is currently not supported. 157 * block size (by default 128K). This is currently not supported.
165 */ 158 */
166 if (PAGE_CACHE_SIZE > msblk->block_size) { 159 if (PAGE_CACHE_SIZE > msblk->block_size) {
167 ERROR("Page size > filesystem block size (%d). This is " 160 ERROR("Page size > filesystem block size (%d). This is "
168 "currently not supported!\n", msblk->block_size); 161 "currently not supported!\n", msblk->block_size);
169 goto failed_mount; 162 goto failed_mount;
170 } 163 }
171 164
172 msblk->block_log = le16_to_cpu(sblk->block_log); 165 msblk->block_log = le16_to_cpu(sblk->block_log);
173 if (msblk->block_log > SQUASHFS_FILE_MAX_LOG) 166 if (msblk->block_log > SQUASHFS_FILE_MAX_LOG)
174 goto failed_mount; 167 goto failed_mount;
175 168
176 /* Check the root inode for sanity */ 169 /* Check the root inode for sanity */
177 root_inode = le64_to_cpu(sblk->root_inode); 170 root_inode = le64_to_cpu(sblk->root_inode);
178 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE) 171 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
179 goto failed_mount; 172 goto failed_mount;
180 173
181 msblk->inode_table = le64_to_cpu(sblk->inode_table_start); 174 msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
182 msblk->directory_table = le64_to_cpu(sblk->directory_table_start); 175 msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
183 msblk->inodes = le32_to_cpu(sblk->inodes); 176 msblk->inodes = le32_to_cpu(sblk->inodes);
184 flags = le16_to_cpu(sblk->flags); 177 flags = le16_to_cpu(sblk->flags);
185 178
186 TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b)); 179 TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
187 TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags) 180 TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
188 ? "un" : ""); 181 ? "un" : "");
189 TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags) 182 TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
190 ? "un" : ""); 183 ? "un" : "");
191 TRACE("Filesystem size %lld bytes\n", msblk->bytes_used); 184 TRACE("Filesystem size %lld bytes\n", msblk->bytes_used);
192 TRACE("Block size %d\n", msblk->block_size); 185 TRACE("Block size %d\n", msblk->block_size);
193 TRACE("Number of inodes %d\n", msblk->inodes); 186 TRACE("Number of inodes %d\n", msblk->inodes);
194 TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments)); 187 TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments));
195 TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids)); 188 TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids));
196 TRACE("sblk->inode_table_start %llx\n", msblk->inode_table); 189 TRACE("sblk->inode_table_start %llx\n", msblk->inode_table);
197 TRACE("sblk->directory_table_start %llx\n", msblk->directory_table); 190 TRACE("sblk->directory_table_start %llx\n", msblk->directory_table);
198 TRACE("sblk->fragment_table_start %llx\n", 191 TRACE("sblk->fragment_table_start %llx\n",
199 (u64) le64_to_cpu(sblk->fragment_table_start)); 192 (u64) le64_to_cpu(sblk->fragment_table_start));
200 TRACE("sblk->id_table_start %llx\n", 193 TRACE("sblk->id_table_start %llx\n",
201 (u64) le64_to_cpu(sblk->id_table_start)); 194 (u64) le64_to_cpu(sblk->id_table_start));
202 195
203 sb->s_maxbytes = MAX_LFS_FILESIZE; 196 sb->s_maxbytes = MAX_LFS_FILESIZE;
204 sb->s_flags |= MS_RDONLY; 197 sb->s_flags |= MS_RDONLY;
205 sb->s_op = &squashfs_super_ops; 198 sb->s_op = &squashfs_super_ops;
206 199
207 err = -ENOMEM; 200 err = -ENOMEM;
208 201
209 msblk->stream = squashfs_decompressor_init(msblk); 202 msblk->stream = squashfs_decompressor_init(msblk);
210 if (msblk->stream == NULL) 203 if (msblk->stream == NULL)
211 goto failed_mount; 204 goto failed_mount;
212 205
213 msblk->block_cache = squashfs_cache_init("metadata", 206 msblk->block_cache = squashfs_cache_init("metadata",
214 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); 207 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
215 if (msblk->block_cache == NULL) 208 if (msblk->block_cache == NULL)
216 goto failed_mount; 209 goto failed_mount;
217 210
218 /* Allocate read_page block */ 211 /* Allocate read_page block */
219 msblk->read_page = squashfs_cache_init("data", 1, msblk->block_size); 212 msblk->read_page = squashfs_cache_init("data", 1, msblk->block_size);
220 if (msblk->read_page == NULL) { 213 if (msblk->read_page == NULL) {
221 ERROR("Failed to allocate read_page block\n"); 214 ERROR("Failed to allocate read_page block\n");
222 goto failed_mount; 215 goto failed_mount;
223 } 216 }
224 217
225 /* Allocate and read id index table */ 218 /* Allocate and read id index table */
226 msblk->id_table = squashfs_read_id_index_table(sb, 219 msblk->id_table = squashfs_read_id_index_table(sb,
227 le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids)); 220 le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids));
228 if (IS_ERR(msblk->id_table)) { 221 if (IS_ERR(msblk->id_table)) {
229 err = PTR_ERR(msblk->id_table); 222 err = PTR_ERR(msblk->id_table);
230 msblk->id_table = NULL; 223 msblk->id_table = NULL;
231 goto failed_mount; 224 goto failed_mount;
232 } 225 }
233 226
234 fragments = le32_to_cpu(sblk->fragments); 227 fragments = le32_to_cpu(sblk->fragments);
235 if (fragments == 0) 228 if (fragments == 0)
236 goto allocate_lookup_table; 229 goto allocate_lookup_table;
237 230
238 msblk->fragment_cache = squashfs_cache_init("fragment", 231 msblk->fragment_cache = squashfs_cache_init("fragment",
239 SQUASHFS_CACHED_FRAGMENTS, msblk->block_size); 232 SQUASHFS_CACHED_FRAGMENTS, msblk->block_size);
240 if (msblk->fragment_cache == NULL) { 233 if (msblk->fragment_cache == NULL) {
241 err = -ENOMEM; 234 err = -ENOMEM;
242 goto failed_mount; 235 goto failed_mount;
243 } 236 }
244 237
245 /* Allocate and read fragment index table */ 238 /* Allocate and read fragment index table */
246 msblk->fragment_index = squashfs_read_fragment_index_table(sb, 239 msblk->fragment_index = squashfs_read_fragment_index_table(sb,
247 le64_to_cpu(sblk->fragment_table_start), fragments); 240 le64_to_cpu(sblk->fragment_table_start), fragments);
248 if (IS_ERR(msblk->fragment_index)) { 241 if (IS_ERR(msblk->fragment_index)) {
249 err = PTR_ERR(msblk->fragment_index); 242 err = PTR_ERR(msblk->fragment_index);
250 msblk->fragment_index = NULL; 243 msblk->fragment_index = NULL;
251 goto failed_mount; 244 goto failed_mount;
252 } 245 }
253 246
254 allocate_lookup_table: 247 allocate_lookup_table:
255 lookup_table_start = le64_to_cpu(sblk->lookup_table_start); 248 lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
256 if (lookup_table_start == SQUASHFS_INVALID_BLK) 249 if (lookup_table_start == SQUASHFS_INVALID_BLK)
257 goto allocate_xattr_table; 250 goto allocate_xattr_table;
258 251
259 /* Allocate and read inode lookup table */ 252 /* Allocate and read inode lookup table */
260 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, 253 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
261 lookup_table_start, msblk->inodes); 254 lookup_table_start, msblk->inodes);
262 if (IS_ERR(msblk->inode_lookup_table)) { 255 if (IS_ERR(msblk->inode_lookup_table)) {
263 err = PTR_ERR(msblk->inode_lookup_table); 256 err = PTR_ERR(msblk->inode_lookup_table);
264 msblk->inode_lookup_table = NULL; 257 msblk->inode_lookup_table = NULL;
265 goto failed_mount; 258 goto failed_mount;
266 } 259 }
267 260
268 sb->s_export_op = &squashfs_export_ops; 261 sb->s_export_op = &squashfs_export_ops;
269 262
270 allocate_xattr_table: 263 allocate_xattr_table:
264 sb->s_xattr = squashfs_xattr_handlers;
271 xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start); 265 xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
272 if (xattr_id_table_start == SQUASHFS_INVALID_BLK) 266 if (xattr_id_table_start == SQUASHFS_INVALID_BLK)
273 goto allocate_root; 267 goto allocate_root;
274 268
275 /* Allocate and read xattr id lookup table */ 269 /* Allocate and read xattr id lookup table */
276 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, 270 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
277 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids); 271 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
278 if (IS_ERR(msblk->xattr_id_table)) { 272 if (IS_ERR(msblk->xattr_id_table)) {
279 err = PTR_ERR(msblk->xattr_id_table); 273 err = PTR_ERR(msblk->xattr_id_table);
280 msblk->xattr_id_table = NULL; 274 msblk->xattr_id_table = NULL;
281 goto failed_mount; 275 goto failed_mount;
282 } 276 }
283 allocate_root: 277 allocate_root:
284 root = new_inode(sb); 278 root = new_inode(sb);
285 if (!root) { 279 if (!root) {
286 err = -ENOMEM; 280 err = -ENOMEM;
287 goto failed_mount; 281 goto failed_mount;
288 } 282 }
289 283
290 err = squashfs_read_inode(root, root_inode); 284 err = squashfs_read_inode(root, root_inode);
291 if (err) { 285 if (err) {
292 make_bad_inode(root); 286 make_bad_inode(root);
293 iput(root); 287 iput(root);
294 goto failed_mount; 288 goto failed_mount;
295 } 289 }
296 insert_inode_hash(root); 290 insert_inode_hash(root);
297 291
298 sb->s_root = d_alloc_root(root); 292 sb->s_root = d_alloc_root(root);
299 if (sb->s_root == NULL) { 293 if (sb->s_root == NULL) {
300 ERROR("Root inode create failed\n"); 294 ERROR("Root inode create failed\n");
301 err = -ENOMEM; 295 err = -ENOMEM;
302 iput(root); 296 iput(root);
303 goto failed_mount; 297 goto failed_mount;
304 } 298 }
305 299
306 TRACE("Leaving squashfs_fill_super\n"); 300 TRACE("Leaving squashfs_fill_super\n");
307 kfree(sblk); 301 kfree(sblk);
308 return 0; 302 return 0;
309 303
310 failed_mount: 304 failed_mount:
311 squashfs_cache_delete(msblk->block_cache); 305 squashfs_cache_delete(msblk->block_cache);
312 squashfs_cache_delete(msblk->fragment_cache); 306 squashfs_cache_delete(msblk->fragment_cache);
313 squashfs_cache_delete(msblk->read_page); 307 squashfs_cache_delete(msblk->read_page);
314 squashfs_decompressor_free(msblk, msblk->stream); 308 squashfs_decompressor_free(msblk, msblk->stream);
315 kfree(msblk->inode_lookup_table); 309 kfree(msblk->inode_lookup_table);
316 kfree(msblk->fragment_index); 310 kfree(msblk->fragment_index);
317 kfree(msblk->id_table); 311 kfree(msblk->id_table);
318 kfree(msblk->xattr_id_table); 312 kfree(msblk->xattr_id_table);
319 kfree(sb->s_fs_info); 313 kfree(sb->s_fs_info);
320 sb->s_fs_info = NULL; 314 sb->s_fs_info = NULL;
321 kfree(sblk); 315 kfree(sblk);
322 return err; 316 return err;
323 317
324 failure: 318 failure:
325 kfree(sb->s_fs_info); 319 kfree(sb->s_fs_info);
326 sb->s_fs_info = NULL; 320 sb->s_fs_info = NULL;
327 return -ENOMEM; 321 return -ENOMEM;
328 } 322 }
329 323
330 324
331 static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) 325 static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
332 { 326 {
333 struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; 327 struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
334 u64 id = huge_encode_dev(dentry->d_sb->s_bdev->bd_dev); 328 u64 id = huge_encode_dev(dentry->d_sb->s_bdev->bd_dev);
335 329
336 TRACE("Entered squashfs_statfs\n"); 330 TRACE("Entered squashfs_statfs\n");
337 331
338 buf->f_type = SQUASHFS_MAGIC; 332 buf->f_type = SQUASHFS_MAGIC;
339 buf->f_bsize = msblk->block_size; 333 buf->f_bsize = msblk->block_size;
340 buf->f_blocks = ((msblk->bytes_used - 1) >> msblk->block_log) + 1; 334 buf->f_blocks = ((msblk->bytes_used - 1) >> msblk->block_log) + 1;
341 buf->f_bfree = buf->f_bavail = 0; 335 buf->f_bfree = buf->f_bavail = 0;
342 buf->f_files = msblk->inodes; 336 buf->f_files = msblk->inodes;
343 buf->f_ffree = 0; 337 buf->f_ffree = 0;
344 buf->f_namelen = SQUASHFS_NAME_LEN; 338 buf->f_namelen = SQUASHFS_NAME_LEN;
345 buf->f_fsid.val[0] = (u32)id; 339 buf->f_fsid.val[0] = (u32)id;
346 buf->f_fsid.val[1] = (u32)(id >> 32); 340 buf->f_fsid.val[1] = (u32)(id >> 32);
347 341
348 return 0; 342 return 0;
349 } 343 }
350 344
351 345
352 static int squashfs_remount(struct super_block *sb, int *flags, char *data) 346 static int squashfs_remount(struct super_block *sb, int *flags, char *data)
353 { 347 {
354 *flags |= MS_RDONLY; 348 *flags |= MS_RDONLY;
355 return 0; 349 return 0;
356 } 350 }
357 351
358 352
359 static void squashfs_put_super(struct super_block *sb) 353 static void squashfs_put_super(struct super_block *sb)
360 { 354 {
361 lock_kernel(); 355 lock_kernel();
362 356
363 if (sb->s_fs_info) { 357 if (sb->s_fs_info) {
364 struct squashfs_sb_info *sbi = sb->s_fs_info; 358 struct squashfs_sb_info *sbi = sb->s_fs_info;
365 squashfs_cache_delete(sbi->block_cache); 359 squashfs_cache_delete(sbi->block_cache);
366 squashfs_cache_delete(sbi->fragment_cache); 360 squashfs_cache_delete(sbi->fragment_cache);
367 squashfs_cache_delete(sbi->read_page); 361 squashfs_cache_delete(sbi->read_page);
368 squashfs_decompressor_free(sbi, sbi->stream); 362 squashfs_decompressor_free(sbi, sbi->stream);
369 kfree(sbi->id_table); 363 kfree(sbi->id_table);
370 kfree(sbi->fragment_index); 364 kfree(sbi->fragment_index);
371 kfree(sbi->meta_index); 365 kfree(sbi->meta_index);
372 kfree(sbi->inode_lookup_table); 366 kfree(sbi->inode_lookup_table);
373 kfree(sbi->xattr_id_table); 367 kfree(sbi->xattr_id_table);
374 kfree(sb->s_fs_info); 368 kfree(sb->s_fs_info);
375 sb->s_fs_info = NULL; 369 sb->s_fs_info = NULL;
376 } 370 }
377 371
378 unlock_kernel(); 372 unlock_kernel();
379 } 373 }
380 374
381 375
382 static int squashfs_get_sb(struct file_system_type *fs_type, int flags, 376 static int squashfs_get_sb(struct file_system_type *fs_type, int flags,
383 const char *dev_name, void *data, 377 const char *dev_name, void *data,
384 struct vfsmount *mnt) 378 struct vfsmount *mnt)
385 { 379 {
386 return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, 380 return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super,
387 mnt); 381 mnt);
388 } 382 }
389 383
390 384
391 static struct kmem_cache *squashfs_inode_cachep; 385 static struct kmem_cache *squashfs_inode_cachep;
392 386
393 387
394 static void init_once(void *foo) 388 static void init_once(void *foo)
395 { 389 {
396 struct squashfs_inode_info *ei = foo; 390 struct squashfs_inode_info *ei = foo;
397 391
398 inode_init_once(&ei->vfs_inode); 392 inode_init_once(&ei->vfs_inode);
399 } 393 }
400 394
401 395
402 static int __init init_inodecache(void) 396 static int __init init_inodecache(void)
403 { 397 {
404 squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", 398 squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
405 sizeof(struct squashfs_inode_info), 0, 399 sizeof(struct squashfs_inode_info), 0,
406 SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once); 400 SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once);
407 401
408 return squashfs_inode_cachep ? 0 : -ENOMEM; 402 return squashfs_inode_cachep ? 0 : -ENOMEM;
409 } 403 }
410 404
411 405
412 static void destroy_inodecache(void) 406 static void destroy_inodecache(void)
413 { 407 {
414 kmem_cache_destroy(squashfs_inode_cachep); 408 kmem_cache_destroy(squashfs_inode_cachep);
415 } 409 }
416 410
417 411
418 static int __init init_squashfs_fs(void) 412 static int __init init_squashfs_fs(void)
419 { 413 {
420 int err = init_inodecache(); 414 int err = init_inodecache();
421 415
422 if (err) 416 if (err)
423 return err; 417 return err;
424 418
425 err = register_filesystem(&squashfs_fs_type); 419 err = register_filesystem(&squashfs_fs_type);
426 if (err) { 420 if (err) {
427 destroy_inodecache(); 421 destroy_inodecache();
428 return err; 422 return err;
429 } 423 }
430 424
431 printk(KERN_INFO "squashfs: version 4.0 (2009/01/31) " 425 printk(KERN_INFO "squashfs: version 4.0 (2009/01/31) "
432 "Phillip Lougher\n"); 426 "Phillip Lougher\n");
433 427
434 return 0; 428 return 0;
435 } 429 }
436 430
437 431
438 static void __exit exit_squashfs_fs(void) 432 static void __exit exit_squashfs_fs(void)
439 { 433 {
440 unregister_filesystem(&squashfs_fs_type); 434 unregister_filesystem(&squashfs_fs_type);
441 destroy_inodecache(); 435 destroy_inodecache();
442 } 436 }
443 437
444 438
445 static struct inode *squashfs_alloc_inode(struct super_block *sb) 439 static struct inode *squashfs_alloc_inode(struct super_block *sb)
446 { 440 {
447 struct squashfs_inode_info *ei = 441 struct squashfs_inode_info *ei =
448 kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); 442 kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
449 443
450 return ei ? &ei->vfs_inode : NULL; 444 return ei ? &ei->vfs_inode : NULL;
451 } 445 }
452 446
453 447
454 static void squashfs_destroy_inode(struct inode *inode) 448 static void squashfs_destroy_inode(struct inode *inode)
455 { 449 {
456 kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode)); 450 kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode));
457 } 451 }
458 452
459 453
460 static struct file_system_type squashfs_fs_type = { 454 static struct file_system_type squashfs_fs_type = {
461 .owner = THIS_MODULE, 455 .owner = THIS_MODULE,
462 .name = "squashfs", 456 .name = "squashfs",
463 .get_sb = squashfs_get_sb, 457 .get_sb = squashfs_get_sb,
464 .kill_sb = kill_block_super, 458 .kill_sb = kill_block_super,
465 .fs_flags = FS_REQUIRES_DEV 459 .fs_flags = FS_REQUIRES_DEV
466 }; 460 };
467 461
468 static const struct super_operations squashfs_super_ops = { 462 static const struct super_operations squashfs_super_ops = {
469 .alloc_inode = squashfs_alloc_inode, 463 .alloc_inode = squashfs_alloc_inode,
470 .destroy_inode = squashfs_destroy_inode, 464 .destroy_inode = squashfs_destroy_inode,
471 .statfs = squashfs_statfs, 465 .statfs = squashfs_statfs,
472 .put_super = squashfs_put_super, 466 .put_super = squashfs_put_super,
473 .remount_fs = squashfs_remount 467 .remount_fs = squashfs_remount
474 }; 468 };
475 469
476 module_init(init_squashfs_fs); 470 module_init(init_squashfs_fs);
477 module_exit(exit_squashfs_fs); 471 module_exit(exit_squashfs_fs);
478 MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem"); 472 MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem");
479 MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>"); 473 MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
480 MODULE_LICENSE("GPL"); 474 MODULE_LICENSE("GPL");
fs/squashfs/symlink.c
1 /* 1 /*
2 * Squashfs - a compressed read only filesystem for Linux 2 * Squashfs - a compressed read only filesystem for Linux
3 * 3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@lougher.demon.co.uk> 5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2, 9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version. 10 * or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 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 18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * 20 *
21 * symlink.c 21 * symlink.c
22 */ 22 */
23 23
24 /* 24 /*
25 * This file implements code to handle symbolic links. 25 * This file implements code to handle symbolic links.
26 * 26 *
27 * The data contents of symbolic links are stored inside the symbolic 27 * The data contents of symbolic links are stored inside the symbolic
28 * link inode within the inode table. This allows the normally small symbolic 28 * link inode within the inode table. This allows the normally small symbolic
29 * link to be compressed as part of the inode table, achieving much greater 29 * link to be compressed as part of the inode table, achieving much greater
30 * compression than if the symbolic link was compressed individually. 30 * compression than if the symbolic link was compressed individually.
31 */ 31 */
32 32
33 #include <linux/fs.h> 33 #include <linux/fs.h>
34 #include <linux/vfs.h> 34 #include <linux/vfs.h>
35 #include <linux/kernel.h> 35 #include <linux/kernel.h>
36 #include <linux/string.h> 36 #include <linux/string.h>
37 #include <linux/pagemap.h> 37 #include <linux/pagemap.h>
38 #include <linux/xattr.h>
38 39
39 #include "squashfs_fs.h" 40 #include "squashfs_fs.h"
40 #include "squashfs_fs_sb.h" 41 #include "squashfs_fs_sb.h"
41 #include "squashfs_fs_i.h" 42 #include "squashfs_fs_i.h"
42 #include "squashfs.h" 43 #include "squashfs.h"
43 44
44 static int squashfs_symlink_readpage(struct file *file, struct page *page) 45 static int squashfs_symlink_readpage(struct file *file, struct page *page)
45 { 46 {
46 struct inode *inode = page->mapping->host; 47 struct inode *inode = page->mapping->host;
47 struct super_block *sb = inode->i_sb; 48 struct super_block *sb = inode->i_sb;
48 struct squashfs_sb_info *msblk = sb->s_fs_info; 49 struct squashfs_sb_info *msblk = sb->s_fs_info;
49 int index = page->index << PAGE_CACHE_SHIFT; 50 int index = page->index << PAGE_CACHE_SHIFT;
50 u64 block = squashfs_i(inode)->start; 51 u64 block = squashfs_i(inode)->start;
51 int offset = squashfs_i(inode)->offset; 52 int offset = squashfs_i(inode)->offset;
52 int length = min_t(int, i_size_read(inode) - index, PAGE_CACHE_SIZE); 53 int length = min_t(int, i_size_read(inode) - index, PAGE_CACHE_SIZE);
53 int bytes, copied; 54 int bytes, copied;
54 void *pageaddr; 55 void *pageaddr;
55 struct squashfs_cache_entry *entry; 56 struct squashfs_cache_entry *entry;
56 57
57 TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " 58 TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
58 "%llx, offset %x\n", page->index, block, offset); 59 "%llx, offset %x\n", page->index, block, offset);
59 60
60 /* 61 /*
61 * Skip index bytes into symlink metadata. 62 * Skip index bytes into symlink metadata.
62 */ 63 */
63 if (index) { 64 if (index) {
64 bytes = squashfs_read_metadata(sb, NULL, &block, &offset, 65 bytes = squashfs_read_metadata(sb, NULL, &block, &offset,
65 index); 66 index);
66 if (bytes < 0) { 67 if (bytes < 0) {
67 ERROR("Unable to read symlink [%llx:%x]\n", 68 ERROR("Unable to read symlink [%llx:%x]\n",
68 squashfs_i(inode)->start, 69 squashfs_i(inode)->start,
69 squashfs_i(inode)->offset); 70 squashfs_i(inode)->offset);
70 goto error_out; 71 goto error_out;
71 } 72 }
72 } 73 }
73 74
74 /* 75 /*
75 * Read length bytes from symlink metadata. Squashfs_read_metadata 76 * Read length bytes from symlink metadata. Squashfs_read_metadata
76 * is not used here because it can sleep and we want to use 77 * is not used here because it can sleep and we want to use
77 * kmap_atomic to map the page. Instead call the underlying 78 * kmap_atomic to map the page. Instead call the underlying
78 * squashfs_cache_get routine. As length bytes may overlap metadata 79 * squashfs_cache_get routine. As length bytes may overlap metadata
79 * blocks, we may need to call squashfs_cache_get multiple times. 80 * blocks, we may need to call squashfs_cache_get multiple times.
80 */ 81 */
81 for (bytes = 0; bytes < length; offset = 0, bytes += copied) { 82 for (bytes = 0; bytes < length; offset = 0, bytes += copied) {
82 entry = squashfs_cache_get(sb, msblk->block_cache, block, 0); 83 entry = squashfs_cache_get(sb, msblk->block_cache, block, 0);
83 if (entry->error) { 84 if (entry->error) {
84 ERROR("Unable to read symlink [%llx:%x]\n", 85 ERROR("Unable to read symlink [%llx:%x]\n",
85 squashfs_i(inode)->start, 86 squashfs_i(inode)->start,
86 squashfs_i(inode)->offset); 87 squashfs_i(inode)->offset);
87 squashfs_cache_put(entry); 88 squashfs_cache_put(entry);
88 goto error_out; 89 goto error_out;
89 } 90 }
90 91
91 pageaddr = kmap_atomic(page, KM_USER0); 92 pageaddr = kmap_atomic(page, KM_USER0);
92 copied = squashfs_copy_data(pageaddr + bytes, entry, offset, 93 copied = squashfs_copy_data(pageaddr + bytes, entry, offset,
93 length - bytes); 94 length - bytes);
94 if (copied == length - bytes) 95 if (copied == length - bytes)
95 memset(pageaddr + length, 0, PAGE_CACHE_SIZE - length); 96 memset(pageaddr + length, 0, PAGE_CACHE_SIZE - length);
96 else 97 else
97 block = entry->next_index; 98 block = entry->next_index;
98 kunmap_atomic(pageaddr, KM_USER0); 99 kunmap_atomic(pageaddr, KM_USER0);
99 squashfs_cache_put(entry); 100 squashfs_cache_put(entry);
100 } 101 }
101 102
102 flush_dcache_page(page); 103 flush_dcache_page(page);
103 SetPageUptodate(page); 104 SetPageUptodate(page);
104 unlock_page(page); 105 unlock_page(page);
105 return 0; 106 return 0;
106 107
107 error_out: 108 error_out:
108 SetPageError(page); 109 SetPageError(page);
109 unlock_page(page); 110 unlock_page(page);
110 return 0; 111 return 0;
111 } 112 }
112 113
113 114
114 const struct address_space_operations squashfs_symlink_aops = { 115 const struct address_space_operations squashfs_symlink_aops = {
115 .readpage = squashfs_symlink_readpage 116 .readpage = squashfs_symlink_readpage
117 };
118
119 const struct inode_operations squashfs_symlink_inode_ops = {
120 .readlink = generic_readlink,
121 .follow_link = page_follow_link_light,
122 .put_link = page_put_link,
123 .getxattr = generic_getxattr,
124 .listxattr = squashfs_listxattr
116 }; 125 };
117 126
127