1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Squashfs - a compressed read only filesystem for Linux 4 * 5 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 6 * Phillip Lougher <phillip@squashfs.org.uk> 7 * 8 * inode.c 9 */ 10 11 /* 12 * This file implements code to create and read inodes from disk. 13 * 14 * Inodes in Squashfs are identified by a 48-bit inode which encodes the 15 * location of the compressed metadata block containing the inode, and the byte 16 * offset into that block where the inode is placed (<block, offset>). 17 * 18 * To maximise compression there are different inodes for each file type 19 * (regular file, directory, device, etc.), the inode contents and length 20 * varying with the type. 21 * 22 * To further maximise compression, two types of regular file inode and 23 * directory inode are defined: inodes optimised for frequently occurring 24 * regular files and directories, and extended types where extra 25 * information has to be stored. 26 */ 27 28 #include <linux/fs.h> 29 #include <linux/vfs.h> 30 #include <linux/xattr.h> 31 #include <linux/pagemap.h> 32 33 #include "squashfs_fs.h" 34 #include "squashfs_fs_sb.h" 35 #include "squashfs_fs_i.h" 36 #include "squashfs.h" 37 #include "xattr.h" 38 39 /* 40 * Initialise VFS inode with the base inode information common to all 41 * Squashfs inode types. Sqsh_ino contains the unswapped base inode 42 * off disk. 43 */ 44 static int squashfs_new_inode(struct super_block *sb, struct inode *inode, 45 struct squashfs_base_inode *sqsh_ino) 46 { 47 uid_t i_uid; 48 gid_t i_gid; 49 int err; 50 51 inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); 52 if (inode->i_ino == 0) 53 return -EINVAL; 54 55 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &i_uid); 56 if (err) 57 return err; 58 59 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &i_gid); 60 if (err) 61 return err; 62 63 i_uid_write(inode, i_uid); 64 i_gid_write(inode, i_gid); 65 inode_set_mtime(inode, le32_to_cpu(sqsh_ino->mtime), 0); 66 inode_set_atime(inode, inode_get_mtime_sec(inode), 0); 67 inode_set_ctime(inode, inode_get_mtime_sec(inode), 0); 68 inode->i_mode = le16_to_cpu(sqsh_ino->mode); 69 inode->i_size = 0; 70 71 /* File type must not be set at this moment, for it will later be set by the caller. */ 72 if (inode->i_mode & S_IFMT) 73 err = -EIO; 74 75 return err; 76 } 77 78 79 struct inode *squashfs_iget(struct super_block *sb, long long ino, 80 unsigned int ino_number) 81 { 82 struct inode *inode = iget_locked(sb, ino_number); 83 int err; 84 85 TRACE("Entered squashfs_iget\n"); 86 87 if (!inode) 88 return ERR_PTR(-ENOMEM); 89 if (!(inode->i_state & I_NEW)) 90 return inode; 91 92 err = squashfs_read_inode(inode, ino); 93 if (err) { 94 iget_failed(inode); 95 return ERR_PTR(err); 96 } 97 98 unlock_new_inode(inode); 99 return inode; 100 } 101 102 103 /* 104 * Initialise VFS inode by reading inode from inode table (compressed 105 * metadata). The format and amount of data read depends on type. 106 */ 107 int squashfs_read_inode(struct inode *inode, long long ino) 108 { 109 struct super_block *sb = inode->i_sb; 110 struct squashfs_sb_info *msblk = sb->s_fs_info; 111 u64 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table; 112 int err, type, offset = SQUASHFS_INODE_OFFSET(ino); 113 union squashfs_inode squashfs_ino; 114 struct squashfs_base_inode *sqshb_ino = &squashfs_ino.base; 115 int xattr_id = SQUASHFS_INVALID_XATTR; 116 117 TRACE("Entered squashfs_read_inode\n"); 118 119 /* 120 * Read inode base common to all inode types. 121 */ 122 err = squashfs_read_metadata(sb, sqshb_ino, &block, 123 &offset, sizeof(*sqshb_ino)); 124 if (err < 0) 125 goto failed_read; 126 127 err = squashfs_new_inode(sb, inode, sqshb_ino); 128 if (err) 129 goto failed_read; 130 131 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table; 132 offset = SQUASHFS_INODE_OFFSET(ino); 133 134 type = le16_to_cpu(sqshb_ino->inode_type); 135 switch (type) { 136 case SQUASHFS_REG_TYPE: { 137 unsigned int frag_offset, frag; 138 int frag_size; 139 u64 frag_blk; 140 struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg; 141 142 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 143 sizeof(*sqsh_ino)); 144 if (err < 0) 145 goto failed_read; 146 147 inode->i_size = le32_to_cpu(sqsh_ino->file_size); 148 frag = le32_to_cpu(sqsh_ino->fragment); 149 if (frag != SQUASHFS_INVALID_FRAG) { 150 /* 151 * the file cannot have a fragment (tailend) and have a 152 * file size a multiple of the block size 153 */ 154 if ((inode->i_size & (msblk->block_size - 1)) == 0) { 155 err = -EINVAL; 156 goto failed_read; 157 } 158 frag_offset = le32_to_cpu(sqsh_ino->offset); 159 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); 160 if (frag_size < 0) { 161 err = frag_size; 162 goto failed_read; 163 } 164 } else { 165 frag_blk = SQUASHFS_INVALID_BLK; 166 frag_size = 0; 167 frag_offset = 0; 168 } 169 170 set_nlink(inode, 1); 171 inode->i_fop = &squashfs_file_operations; 172 inode->i_mode |= S_IFREG; 173 inode->i_blocks = ((inode->i_size - 1) >> 9) + 1; 174 squashfs_i(inode)->fragment_block = frag_blk; 175 squashfs_i(inode)->fragment_size = frag_size; 176 squashfs_i(inode)->fragment_offset = frag_offset; 177 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 178 squashfs_i(inode)->block_list_start = block; 179 squashfs_i(inode)->offset = offset; 180 squashfs_i(inode)->parent = 0; 181 inode->i_data.a_ops = &squashfs_aops; 182 183 TRACE("File inode %x:%x, start_block %llx, block_list_start " 184 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino), 185 offset, squashfs_i(inode)->start, block, offset); 186 break; 187 } 188 case SQUASHFS_LREG_TYPE: { 189 unsigned int frag_offset, frag; 190 int frag_size; 191 u64 frag_blk; 192 struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; 193 194 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 195 sizeof(*sqsh_ino)); 196 if (err < 0) 197 goto failed_read; 198 199 inode->i_size = le64_to_cpu(sqsh_ino->file_size); 200 if (inode->i_size < 0) { 201 err = -EINVAL; 202 goto failed_read; 203 } 204 frag = le32_to_cpu(sqsh_ino->fragment); 205 if (frag != SQUASHFS_INVALID_FRAG) { 206 /* 207 * the file cannot have a fragment (tailend) and have a 208 * file size a multiple of the block size 209 */ 210 if ((inode->i_size & (msblk->block_size - 1)) == 0) { 211 err = -EINVAL; 212 goto failed_read; 213 } 214 frag_offset = le32_to_cpu(sqsh_ino->offset); 215 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); 216 if (frag_size < 0) { 217 err = frag_size; 218 goto failed_read; 219 } 220 } else { 221 frag_blk = SQUASHFS_INVALID_BLK; 222 frag_size = 0; 223 frag_offset = 0; 224 } 225 226 xattr_id = le32_to_cpu(sqsh_ino->xattr); 227 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 228 inode->i_op = &squashfs_inode_ops; 229 inode->i_fop = &squashfs_file_operations; 230 inode->i_mode |= S_IFREG; 231 inode->i_blocks = (inode->i_size - 232 le64_to_cpu(sqsh_ino->sparse) + 511) >> 9; 233 234 squashfs_i(inode)->fragment_block = frag_blk; 235 squashfs_i(inode)->fragment_size = frag_size; 236 squashfs_i(inode)->fragment_offset = frag_offset; 237 squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block); 238 squashfs_i(inode)->block_list_start = block; 239 squashfs_i(inode)->offset = offset; 240 squashfs_i(inode)->parent = 0; 241 inode->i_data.a_ops = &squashfs_aops; 242 243 TRACE("File inode %x:%x, start_block %llx, block_list_start " 244 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino), 245 offset, squashfs_i(inode)->start, block, offset); 246 break; 247 } 248 case SQUASHFS_DIR_TYPE: { 249 struct squashfs_dir_inode *sqsh_ino = &squashfs_ino.dir; 250 251 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 252 sizeof(*sqsh_ino)); 253 if (err < 0) 254 goto failed_read; 255 256 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 257 inode->i_size = le16_to_cpu(sqsh_ino->file_size); 258 inode->i_op = &squashfs_dir_inode_ops; 259 inode->i_fop = &squashfs_dir_ops; 260 inode->i_mode |= S_IFDIR; 261 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 262 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset); 263 squashfs_i(inode)->dir_idx_cnt = 0; 264 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode); 265 266 TRACE("Directory inode %x:%x, start_block %llx, offset %x\n", 267 SQUASHFS_INODE_BLK(ino), offset, 268 squashfs_i(inode)->start, 269 le16_to_cpu(sqsh_ino->offset)); 270 break; 271 } 272 case SQUASHFS_LDIR_TYPE: { 273 struct squashfs_ldir_inode *sqsh_ino = &squashfs_ino.ldir; 274 275 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 276 sizeof(*sqsh_ino)); 277 if (err < 0) 278 goto failed_read; 279 280 xattr_id = le32_to_cpu(sqsh_ino->xattr); 281 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 282 inode->i_size = le32_to_cpu(sqsh_ino->file_size); 283 inode->i_op = &squashfs_dir_inode_ops; 284 inode->i_fop = &squashfs_dir_ops; 285 inode->i_mode |= S_IFDIR; 286 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 287 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset); 288 squashfs_i(inode)->dir_idx_start = block; 289 squashfs_i(inode)->dir_idx_offset = offset; 290 squashfs_i(inode)->dir_idx_cnt = le16_to_cpu(sqsh_ino->i_count); 291 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode); 292 293 TRACE("Long directory inode %x:%x, start_block %llx, offset " 294 "%x\n", SQUASHFS_INODE_BLK(ino), offset, 295 squashfs_i(inode)->start, 296 le16_to_cpu(sqsh_ino->offset)); 297 break; 298 } 299 case SQUASHFS_SYMLINK_TYPE: 300 case SQUASHFS_LSYMLINK_TYPE: { 301 struct squashfs_symlink_inode *sqsh_ino = &squashfs_ino.symlink; 302 303 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 304 sizeof(*sqsh_ino)); 305 if (err < 0) 306 goto failed_read; 307 308 inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); 309 if (inode->i_size > PAGE_SIZE) { 310 ERROR("Corrupted symlink\n"); 311 return -EINVAL; 312 } 313 314 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 315 inode->i_op = &squashfs_symlink_inode_ops; 316 inode_nohighmem(inode); 317 inode->i_data.a_ops = &squashfs_symlink_aops; 318 inode->i_mode |= S_IFLNK; 319 squashfs_i(inode)->start = block; 320 squashfs_i(inode)->offset = offset; 321 squashfs_i(inode)->parent = 0; 322 323 if (type == SQUASHFS_LSYMLINK_TYPE) { 324 __le32 xattr; 325 326 err = squashfs_read_metadata(sb, NULL, &block, 327 &offset, inode->i_size); 328 if (err < 0) 329 goto failed_read; 330 err = squashfs_read_metadata(sb, &xattr, &block, 331 &offset, sizeof(xattr)); 332 if (err < 0) 333 goto failed_read; 334 xattr_id = le32_to_cpu(xattr); 335 } 336 337 TRACE("Symbolic link inode %x:%x, start_block %llx, offset " 338 "%x\n", SQUASHFS_INODE_BLK(ino), offset, 339 block, offset); 340 break; 341 } 342 case SQUASHFS_BLKDEV_TYPE: 343 case SQUASHFS_CHRDEV_TYPE: { 344 struct squashfs_dev_inode *sqsh_ino = &squashfs_ino.dev; 345 unsigned int rdev; 346 347 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 348 sizeof(*sqsh_ino)); 349 if (err < 0) 350 goto failed_read; 351 352 if (type == SQUASHFS_CHRDEV_TYPE) 353 inode->i_mode |= S_IFCHR; 354 else 355 inode->i_mode |= S_IFBLK; 356 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 357 rdev = le32_to_cpu(sqsh_ino->rdev); 358 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); 359 squashfs_i(inode)->parent = 0; 360 361 TRACE("Device inode %x:%x, rdev %x\n", 362 SQUASHFS_INODE_BLK(ino), offset, rdev); 363 break; 364 } 365 case SQUASHFS_LBLKDEV_TYPE: 366 case SQUASHFS_LCHRDEV_TYPE: { 367 struct squashfs_ldev_inode *sqsh_ino = &squashfs_ino.ldev; 368 unsigned int rdev; 369 370 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 371 sizeof(*sqsh_ino)); 372 if (err < 0) 373 goto failed_read; 374 375 if (type == SQUASHFS_LCHRDEV_TYPE) 376 inode->i_mode |= S_IFCHR; 377 else 378 inode->i_mode |= S_IFBLK; 379 xattr_id = le32_to_cpu(sqsh_ino->xattr); 380 inode->i_op = &squashfs_inode_ops; 381 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 382 rdev = le32_to_cpu(sqsh_ino->rdev); 383 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); 384 squashfs_i(inode)->parent = 0; 385 386 TRACE("Device inode %x:%x, rdev %x\n", 387 SQUASHFS_INODE_BLK(ino), offset, rdev); 388 break; 389 } 390 case SQUASHFS_FIFO_TYPE: 391 case SQUASHFS_SOCKET_TYPE: { 392 struct squashfs_ipc_inode *sqsh_ino = &squashfs_ino.ipc; 393 394 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 395 sizeof(*sqsh_ino)); 396 if (err < 0) 397 goto failed_read; 398 399 if (type == SQUASHFS_FIFO_TYPE) 400 inode->i_mode |= S_IFIFO; 401 else 402 inode->i_mode |= S_IFSOCK; 403 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 404 init_special_inode(inode, inode->i_mode, 0); 405 squashfs_i(inode)->parent = 0; 406 break; 407 } 408 case SQUASHFS_LFIFO_TYPE: 409 case SQUASHFS_LSOCKET_TYPE: { 410 struct squashfs_lipc_inode *sqsh_ino = &squashfs_ino.lipc; 411 412 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 413 sizeof(*sqsh_ino)); 414 if (err < 0) 415 goto failed_read; 416 417 if (type == SQUASHFS_LFIFO_TYPE) 418 inode->i_mode |= S_IFIFO; 419 else 420 inode->i_mode |= S_IFSOCK; 421 xattr_id = le32_to_cpu(sqsh_ino->xattr); 422 inode->i_op = &squashfs_inode_ops; 423 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 424 init_special_inode(inode, inode->i_mode, 0); 425 squashfs_i(inode)->parent = 0; 426 break; 427 } 428 default: 429 ERROR("Unknown inode type %d in squashfs_iget!\n", type); 430 return -EINVAL; 431 } 432 433 if (xattr_id != SQUASHFS_INVALID_XATTR && msblk->xattr_id_table) { 434 err = squashfs_xattr_lookup(sb, xattr_id, 435 &squashfs_i(inode)->xattr_count, 436 &squashfs_i(inode)->xattr_size, 437 &squashfs_i(inode)->xattr); 438 if (err < 0) 439 goto failed_read; 440 inode->i_blocks += ((squashfs_i(inode)->xattr_size - 1) >> 9) 441 + 1; 442 } else 443 squashfs_i(inode)->xattr_count = 0; 444 445 return 0; 446 447 failed_read: 448 ERROR("Unable to read inode 0x%llx\n", ino); 449 return err; 450 } 451 452 453 const struct inode_operations squashfs_inode_ops = { 454 .listxattr = squashfs_listxattr 455 }; 456 457