2 * Squashfs - a compressed read only filesystem for Linux
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@squashfs.org.uk>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 * This file implements code to create and read inodes from disk.
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
29 * offset into that block where the inode is placed (<block, offset>).
31 * To maximise compression there are different inodes for each file type
32 * (regular file, directory, device, etc.), the inode contents and length
33 * varying with the type.
35 * To further maximise compression, two types of regular file inode and
36 * directory inode are defined: inodes optimised for frequently occurring
37 * regular files and directories, and extended types where extra
38 * information has to be stored.
42 #include <linux/vfs.h>
43 #include <linux/xattr.h>
44 #include <linux/pagemap.h>
46 #include "squashfs_fs.h"
47 #include "squashfs_fs_sb.h"
48 #include "squashfs_fs_i.h"
53 * Initialise VFS inode with the base inode information common to all
54 * Squashfs inode types. Sqsh_ino contains the unswapped base inode
57 static int squashfs_new_inode(struct super_block
*sb
, struct inode
*inode
,
58 struct squashfs_base_inode
*sqsh_ino
)
64 err
= squashfs_get_id(sb
, le16_to_cpu(sqsh_ino
->uid
), &i_uid
);
68 err
= squashfs_get_id(sb
, le16_to_cpu(sqsh_ino
->guid
), &i_gid
);
72 i_uid_write(inode
, i_uid
);
73 i_gid_write(inode
, i_gid
);
74 inode
->i_ino
= le32_to_cpu(sqsh_ino
->inode_number
);
75 inode
->i_mtime
.tv_sec
= le32_to_cpu(sqsh_ino
->mtime
);
76 inode
->i_atime
.tv_sec
= inode
->i_mtime
.tv_sec
;
77 inode
->i_ctime
.tv_sec
= inode
->i_mtime
.tv_sec
;
78 inode
->i_mode
= le16_to_cpu(sqsh_ino
->mode
);
85 struct inode
*squashfs_iget(struct super_block
*sb
, long long ino
,
86 unsigned int ino_number
)
88 struct inode
*inode
= iget_locked(sb
, ino_number
);
91 TRACE("Entered squashfs_iget\n");
94 return ERR_PTR(-ENOMEM
);
95 if (!(inode
->i_state
& I_NEW
))
98 err
= squashfs_read_inode(inode
, ino
);
104 unlock_new_inode(inode
);
110 * Initialise VFS inode by reading inode from inode table (compressed
111 * metadata). The format and amount of data read depends on type.
113 int squashfs_read_inode(struct inode
*inode
, long long ino
)
115 struct super_block
*sb
= inode
->i_sb
;
116 struct squashfs_sb_info
*msblk
= sb
->s_fs_info
;
117 u64 block
= SQUASHFS_INODE_BLK(ino
) + msblk
->inode_table
;
118 int err
, type
, offset
= SQUASHFS_INODE_OFFSET(ino
);
119 union squashfs_inode squashfs_ino
;
120 struct squashfs_base_inode
*sqshb_ino
= &squashfs_ino
.base
;
121 int xattr_id
= SQUASHFS_INVALID_XATTR
;
123 TRACE("Entered squashfs_read_inode\n");
126 * Read inode base common to all inode types.
128 err
= squashfs_read_metadata(sb
, sqshb_ino
, &block
,
129 &offset
, sizeof(*sqshb_ino
));
133 err
= squashfs_new_inode(sb
, inode
, sqshb_ino
);
137 block
= SQUASHFS_INODE_BLK(ino
) + msblk
->inode_table
;
138 offset
= SQUASHFS_INODE_OFFSET(ino
);
140 type
= le16_to_cpu(sqshb_ino
->inode_type
);
142 case SQUASHFS_REG_TYPE
: {
143 unsigned int frag_offset
, frag
;
146 struct squashfs_reg_inode
*sqsh_ino
= &squashfs_ino
.reg
;
148 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
153 frag
= le32_to_cpu(sqsh_ino
->fragment
);
154 if (frag
!= SQUASHFS_INVALID_FRAG
) {
155 frag_offset
= le32_to_cpu(sqsh_ino
->offset
);
156 frag_size
= squashfs_frag_lookup(sb
, frag
, &frag_blk
);
162 frag_blk
= SQUASHFS_INVALID_BLK
;
168 inode
->i_size
= le32_to_cpu(sqsh_ino
->file_size
);
169 inode
->i_fop
= &generic_ro_fops
;
170 inode
->i_mode
|= S_IFREG
;
171 inode
->i_blocks
= ((inode
->i_size
- 1) >> 9) + 1;
172 squashfs_i(inode
)->fragment_block
= frag_blk
;
173 squashfs_i(inode
)->fragment_size
= frag_size
;
174 squashfs_i(inode
)->fragment_offset
= frag_offset
;
175 squashfs_i(inode
)->start
= le32_to_cpu(sqsh_ino
->start_block
);
176 squashfs_i(inode
)->block_list_start
= block
;
177 squashfs_i(inode
)->offset
= offset
;
178 inode
->i_data
.a_ops
= &squashfs_aops
;
180 TRACE("File inode %x:%x, start_block %llx, block_list_start "
181 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino
),
182 offset
, squashfs_i(inode
)->start
, block
, offset
);
185 case SQUASHFS_LREG_TYPE
: {
186 unsigned int frag_offset
, frag
;
189 struct squashfs_lreg_inode
*sqsh_ino
= &squashfs_ino
.lreg
;
191 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
196 frag
= le32_to_cpu(sqsh_ino
->fragment
);
197 if (frag
!= SQUASHFS_INVALID_FRAG
) {
198 frag_offset
= le32_to_cpu(sqsh_ino
->offset
);
199 frag_size
= squashfs_frag_lookup(sb
, frag
, &frag_blk
);
205 frag_blk
= SQUASHFS_INVALID_BLK
;
210 xattr_id
= le32_to_cpu(sqsh_ino
->xattr
);
211 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
212 inode
->i_size
= le64_to_cpu(sqsh_ino
->file_size
);
213 inode
->i_op
= &squashfs_inode_ops
;
214 inode
->i_fop
= &generic_ro_fops
;
215 inode
->i_mode
|= S_IFREG
;
216 inode
->i_blocks
= (inode
->i_size
-
217 le64_to_cpu(sqsh_ino
->sparse
) + 511) >> 9;
219 squashfs_i(inode
)->fragment_block
= frag_blk
;
220 squashfs_i(inode
)->fragment_size
= frag_size
;
221 squashfs_i(inode
)->fragment_offset
= frag_offset
;
222 squashfs_i(inode
)->start
= le64_to_cpu(sqsh_ino
->start_block
);
223 squashfs_i(inode
)->block_list_start
= block
;
224 squashfs_i(inode
)->offset
= offset
;
225 inode
->i_data
.a_ops
= &squashfs_aops
;
227 TRACE("File inode %x:%x, start_block %llx, block_list_start "
228 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino
),
229 offset
, squashfs_i(inode
)->start
, block
, offset
);
232 case SQUASHFS_DIR_TYPE
: {
233 struct squashfs_dir_inode
*sqsh_ino
= &squashfs_ino
.dir
;
235 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
240 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
241 inode
->i_size
= le16_to_cpu(sqsh_ino
->file_size
);
242 inode
->i_op
= &squashfs_dir_inode_ops
;
243 inode
->i_fop
= &squashfs_dir_ops
;
244 inode
->i_mode
|= S_IFDIR
;
245 squashfs_i(inode
)->start
= le32_to_cpu(sqsh_ino
->start_block
);
246 squashfs_i(inode
)->offset
= le16_to_cpu(sqsh_ino
->offset
);
247 squashfs_i(inode
)->dir_idx_cnt
= 0;
248 squashfs_i(inode
)->parent
= le32_to_cpu(sqsh_ino
->parent_inode
);
250 TRACE("Directory inode %x:%x, start_block %llx, offset %x\n",
251 SQUASHFS_INODE_BLK(ino
), offset
,
252 squashfs_i(inode
)->start
,
253 le16_to_cpu(sqsh_ino
->offset
));
256 case SQUASHFS_LDIR_TYPE
: {
257 struct squashfs_ldir_inode
*sqsh_ino
= &squashfs_ino
.ldir
;
259 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
264 xattr_id
= le32_to_cpu(sqsh_ino
->xattr
);
265 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
266 inode
->i_size
= le32_to_cpu(sqsh_ino
->file_size
);
267 inode
->i_op
= &squashfs_dir_inode_ops
;
268 inode
->i_fop
= &squashfs_dir_ops
;
269 inode
->i_mode
|= S_IFDIR
;
270 squashfs_i(inode
)->start
= le32_to_cpu(sqsh_ino
->start_block
);
271 squashfs_i(inode
)->offset
= le16_to_cpu(sqsh_ino
->offset
);
272 squashfs_i(inode
)->dir_idx_start
= block
;
273 squashfs_i(inode
)->dir_idx_offset
= offset
;
274 squashfs_i(inode
)->dir_idx_cnt
= le16_to_cpu(sqsh_ino
->i_count
);
275 squashfs_i(inode
)->parent
= le32_to_cpu(sqsh_ino
->parent_inode
);
277 TRACE("Long directory inode %x:%x, start_block %llx, offset "
278 "%x\n", SQUASHFS_INODE_BLK(ino
), offset
,
279 squashfs_i(inode
)->start
,
280 le16_to_cpu(sqsh_ino
->offset
));
283 case SQUASHFS_SYMLINK_TYPE
:
284 case SQUASHFS_LSYMLINK_TYPE
: {
285 struct squashfs_symlink_inode
*sqsh_ino
= &squashfs_ino
.symlink
;
287 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
292 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
293 inode
->i_size
= le32_to_cpu(sqsh_ino
->symlink_size
);
294 inode
->i_op
= &squashfs_symlink_inode_ops
;
295 inode_nohighmem(inode
);
296 inode
->i_data
.a_ops
= &squashfs_symlink_aops
;
297 inode
->i_mode
|= S_IFLNK
;
298 squashfs_i(inode
)->start
= block
;
299 squashfs_i(inode
)->offset
= offset
;
301 if (type
== SQUASHFS_LSYMLINK_TYPE
) {
304 err
= squashfs_read_metadata(sb
, NULL
, &block
,
305 &offset
, inode
->i_size
);
308 err
= squashfs_read_metadata(sb
, &xattr
, &block
,
309 &offset
, sizeof(xattr
));
312 xattr_id
= le32_to_cpu(xattr
);
315 TRACE("Symbolic link inode %x:%x, start_block %llx, offset "
316 "%x\n", SQUASHFS_INODE_BLK(ino
), offset
,
320 case SQUASHFS_BLKDEV_TYPE
:
321 case SQUASHFS_CHRDEV_TYPE
: {
322 struct squashfs_dev_inode
*sqsh_ino
= &squashfs_ino
.dev
;
325 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
330 if (type
== SQUASHFS_CHRDEV_TYPE
)
331 inode
->i_mode
|= S_IFCHR
;
333 inode
->i_mode
|= S_IFBLK
;
334 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
335 rdev
= le32_to_cpu(sqsh_ino
->rdev
);
336 init_special_inode(inode
, inode
->i_mode
, new_decode_dev(rdev
));
338 TRACE("Device inode %x:%x, rdev %x\n",
339 SQUASHFS_INODE_BLK(ino
), offset
, rdev
);
342 case SQUASHFS_LBLKDEV_TYPE
:
343 case SQUASHFS_LCHRDEV_TYPE
: {
344 struct squashfs_ldev_inode
*sqsh_ino
= &squashfs_ino
.ldev
;
347 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
352 if (type
== SQUASHFS_LCHRDEV_TYPE
)
353 inode
->i_mode
|= S_IFCHR
;
355 inode
->i_mode
|= S_IFBLK
;
356 xattr_id
= le32_to_cpu(sqsh_ino
->xattr
);
357 inode
->i_op
= &squashfs_inode_ops
;
358 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
359 rdev
= le32_to_cpu(sqsh_ino
->rdev
);
360 init_special_inode(inode
, inode
->i_mode
, new_decode_dev(rdev
));
362 TRACE("Device inode %x:%x, rdev %x\n",
363 SQUASHFS_INODE_BLK(ino
), offset
, rdev
);
366 case SQUASHFS_FIFO_TYPE
:
367 case SQUASHFS_SOCKET_TYPE
: {
368 struct squashfs_ipc_inode
*sqsh_ino
= &squashfs_ino
.ipc
;
370 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
375 if (type
== SQUASHFS_FIFO_TYPE
)
376 inode
->i_mode
|= S_IFIFO
;
378 inode
->i_mode
|= S_IFSOCK
;
379 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
380 init_special_inode(inode
, inode
->i_mode
, 0);
383 case SQUASHFS_LFIFO_TYPE
:
384 case SQUASHFS_LSOCKET_TYPE
: {
385 struct squashfs_lipc_inode
*sqsh_ino
= &squashfs_ino
.lipc
;
387 err
= squashfs_read_metadata(sb
, sqsh_ino
, &block
, &offset
,
392 if (type
== SQUASHFS_LFIFO_TYPE
)
393 inode
->i_mode
|= S_IFIFO
;
395 inode
->i_mode
|= S_IFSOCK
;
396 xattr_id
= le32_to_cpu(sqsh_ino
->xattr
);
397 inode
->i_op
= &squashfs_inode_ops
;
398 set_nlink(inode
, le32_to_cpu(sqsh_ino
->nlink
));
399 init_special_inode(inode
, inode
->i_mode
, 0);
403 ERROR("Unknown inode type %d in squashfs_iget!\n", type
);
407 if (xattr_id
!= SQUASHFS_INVALID_XATTR
&& msblk
->xattr_id_table
) {
408 err
= squashfs_xattr_lookup(sb
, xattr_id
,
409 &squashfs_i(inode
)->xattr_count
,
410 &squashfs_i(inode
)->xattr_size
,
411 &squashfs_i(inode
)->xattr
);
414 inode
->i_blocks
+= ((squashfs_i(inode
)->xattr_size
- 1) >> 9)
417 squashfs_i(inode
)->xattr_count
= 0;
422 ERROR("Unable to read inode 0x%llx\n", ino
);
427 const struct inode_operations squashfs_inode_ops
= {
428 .listxattr
= squashfs_listxattr