inode.c (12088B)
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 */ 44static 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 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &i_uid); 52 if (err) 53 return err; 54 55 err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &i_gid); 56 if (err) 57 return err; 58 59 i_uid_write(inode, i_uid); 60 i_gid_write(inode, i_gid); 61 inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); 62 inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime); 63 inode->i_atime.tv_sec = inode->i_mtime.tv_sec; 64 inode->i_ctime.tv_sec = inode->i_mtime.tv_sec; 65 inode->i_mode = le16_to_cpu(sqsh_ino->mode); 66 inode->i_size = 0; 67 68 return err; 69} 70 71 72struct inode *squashfs_iget(struct super_block *sb, long long ino, 73 unsigned int ino_number) 74{ 75 struct inode *inode = iget_locked(sb, ino_number); 76 int err; 77 78 TRACE("Entered squashfs_iget\n"); 79 80 if (!inode) 81 return ERR_PTR(-ENOMEM); 82 if (!(inode->i_state & I_NEW)) 83 return inode; 84 85 err = squashfs_read_inode(inode, ino); 86 if (err) { 87 iget_failed(inode); 88 return ERR_PTR(err); 89 } 90 91 unlock_new_inode(inode); 92 return inode; 93} 94 95 96/* 97 * Initialise VFS inode by reading inode from inode table (compressed 98 * metadata). The format and amount of data read depends on type. 99 */ 100int squashfs_read_inode(struct inode *inode, long long ino) 101{ 102 struct super_block *sb = inode->i_sb; 103 struct squashfs_sb_info *msblk = sb->s_fs_info; 104 u64 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table; 105 int err, type, offset = SQUASHFS_INODE_OFFSET(ino); 106 union squashfs_inode squashfs_ino; 107 struct squashfs_base_inode *sqshb_ino = &squashfs_ino.base; 108 int xattr_id = SQUASHFS_INVALID_XATTR; 109 110 TRACE("Entered squashfs_read_inode\n"); 111 112 /* 113 * Read inode base common to all inode types. 114 */ 115 err = squashfs_read_metadata(sb, sqshb_ino, &block, 116 &offset, sizeof(*sqshb_ino)); 117 if (err < 0) 118 goto failed_read; 119 120 err = squashfs_new_inode(sb, inode, sqshb_ino); 121 if (err) 122 goto failed_read; 123 124 block = SQUASHFS_INODE_BLK(ino) + msblk->inode_table; 125 offset = SQUASHFS_INODE_OFFSET(ino); 126 127 type = le16_to_cpu(sqshb_ino->inode_type); 128 switch (type) { 129 case SQUASHFS_REG_TYPE: { 130 unsigned int frag_offset, frag; 131 int frag_size; 132 u64 frag_blk; 133 struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg; 134 135 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 136 sizeof(*sqsh_ino)); 137 if (err < 0) 138 goto failed_read; 139 140 frag = le32_to_cpu(sqsh_ino->fragment); 141 if (frag != SQUASHFS_INVALID_FRAG) { 142 frag_offset = le32_to_cpu(sqsh_ino->offset); 143 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); 144 if (frag_size < 0) { 145 err = frag_size; 146 goto failed_read; 147 } 148 } else { 149 frag_blk = SQUASHFS_INVALID_BLK; 150 frag_size = 0; 151 frag_offset = 0; 152 } 153 154 set_nlink(inode, 1); 155 inode->i_size = le32_to_cpu(sqsh_ino->file_size); 156 inode->i_fop = &generic_ro_fops; 157 inode->i_mode |= S_IFREG; 158 inode->i_blocks = ((inode->i_size - 1) >> 9) + 1; 159 squashfs_i(inode)->fragment_block = frag_blk; 160 squashfs_i(inode)->fragment_size = frag_size; 161 squashfs_i(inode)->fragment_offset = frag_offset; 162 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 163 squashfs_i(inode)->block_list_start = block; 164 squashfs_i(inode)->offset = offset; 165 inode->i_data.a_ops = &squashfs_aops; 166 167 TRACE("File inode %x:%x, start_block %llx, block_list_start " 168 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino), 169 offset, squashfs_i(inode)->start, block, offset); 170 break; 171 } 172 case SQUASHFS_LREG_TYPE: { 173 unsigned int frag_offset, frag; 174 int frag_size; 175 u64 frag_blk; 176 struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; 177 178 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 179 sizeof(*sqsh_ino)); 180 if (err < 0) 181 goto failed_read; 182 183 frag = le32_to_cpu(sqsh_ino->fragment); 184 if (frag != SQUASHFS_INVALID_FRAG) { 185 frag_offset = le32_to_cpu(sqsh_ino->offset); 186 frag_size = squashfs_frag_lookup(sb, frag, &frag_blk); 187 if (frag_size < 0) { 188 err = frag_size; 189 goto failed_read; 190 } 191 } else { 192 frag_blk = SQUASHFS_INVALID_BLK; 193 frag_size = 0; 194 frag_offset = 0; 195 } 196 197 xattr_id = le32_to_cpu(sqsh_ino->xattr); 198 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 199 inode->i_size = le64_to_cpu(sqsh_ino->file_size); 200 inode->i_op = &squashfs_inode_ops; 201 inode->i_fop = &generic_ro_fops; 202 inode->i_mode |= S_IFREG; 203 inode->i_blocks = (inode->i_size - 204 le64_to_cpu(sqsh_ino->sparse) + 511) >> 9; 205 206 squashfs_i(inode)->fragment_block = frag_blk; 207 squashfs_i(inode)->fragment_size = frag_size; 208 squashfs_i(inode)->fragment_offset = frag_offset; 209 squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block); 210 squashfs_i(inode)->block_list_start = block; 211 squashfs_i(inode)->offset = offset; 212 inode->i_data.a_ops = &squashfs_aops; 213 214 TRACE("File inode %x:%x, start_block %llx, block_list_start " 215 "%llx, offset %x\n", SQUASHFS_INODE_BLK(ino), 216 offset, squashfs_i(inode)->start, block, offset); 217 break; 218 } 219 case SQUASHFS_DIR_TYPE: { 220 struct squashfs_dir_inode *sqsh_ino = &squashfs_ino.dir; 221 222 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 223 sizeof(*sqsh_ino)); 224 if (err < 0) 225 goto failed_read; 226 227 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 228 inode->i_size = le16_to_cpu(sqsh_ino->file_size); 229 inode->i_op = &squashfs_dir_inode_ops; 230 inode->i_fop = &squashfs_dir_ops; 231 inode->i_mode |= S_IFDIR; 232 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 233 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset); 234 squashfs_i(inode)->dir_idx_cnt = 0; 235 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode); 236 237 TRACE("Directory inode %x:%x, start_block %llx, offset %x\n", 238 SQUASHFS_INODE_BLK(ino), offset, 239 squashfs_i(inode)->start, 240 le16_to_cpu(sqsh_ino->offset)); 241 break; 242 } 243 case SQUASHFS_LDIR_TYPE: { 244 struct squashfs_ldir_inode *sqsh_ino = &squashfs_ino.ldir; 245 246 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 247 sizeof(*sqsh_ino)); 248 if (err < 0) 249 goto failed_read; 250 251 xattr_id = le32_to_cpu(sqsh_ino->xattr); 252 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 253 inode->i_size = le32_to_cpu(sqsh_ino->file_size); 254 inode->i_op = &squashfs_dir_inode_ops; 255 inode->i_fop = &squashfs_dir_ops; 256 inode->i_mode |= S_IFDIR; 257 squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block); 258 squashfs_i(inode)->offset = le16_to_cpu(sqsh_ino->offset); 259 squashfs_i(inode)->dir_idx_start = block; 260 squashfs_i(inode)->dir_idx_offset = offset; 261 squashfs_i(inode)->dir_idx_cnt = le16_to_cpu(sqsh_ino->i_count); 262 squashfs_i(inode)->parent = le32_to_cpu(sqsh_ino->parent_inode); 263 264 TRACE("Long directory inode %x:%x, start_block %llx, offset " 265 "%x\n", SQUASHFS_INODE_BLK(ino), offset, 266 squashfs_i(inode)->start, 267 le16_to_cpu(sqsh_ino->offset)); 268 break; 269 } 270 case SQUASHFS_SYMLINK_TYPE: 271 case SQUASHFS_LSYMLINK_TYPE: { 272 struct squashfs_symlink_inode *sqsh_ino = &squashfs_ino.symlink; 273 274 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 275 sizeof(*sqsh_ino)); 276 if (err < 0) 277 goto failed_read; 278 279 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 280 inode->i_size = le32_to_cpu(sqsh_ino->symlink_size); 281 inode->i_op = &squashfs_symlink_inode_ops; 282 inode_nohighmem(inode); 283 inode->i_data.a_ops = &squashfs_symlink_aops; 284 inode->i_mode |= S_IFLNK; 285 squashfs_i(inode)->start = block; 286 squashfs_i(inode)->offset = offset; 287 288 if (type == SQUASHFS_LSYMLINK_TYPE) { 289 __le32 xattr; 290 291 err = squashfs_read_metadata(sb, NULL, &block, 292 &offset, inode->i_size); 293 if (err < 0) 294 goto failed_read; 295 err = squashfs_read_metadata(sb, &xattr, &block, 296 &offset, sizeof(xattr)); 297 if (err < 0) 298 goto failed_read; 299 xattr_id = le32_to_cpu(xattr); 300 } 301 302 TRACE("Symbolic link inode %x:%x, start_block %llx, offset " 303 "%x\n", SQUASHFS_INODE_BLK(ino), offset, 304 block, offset); 305 break; 306 } 307 case SQUASHFS_BLKDEV_TYPE: 308 case SQUASHFS_CHRDEV_TYPE: { 309 struct squashfs_dev_inode *sqsh_ino = &squashfs_ino.dev; 310 unsigned int rdev; 311 312 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 313 sizeof(*sqsh_ino)); 314 if (err < 0) 315 goto failed_read; 316 317 if (type == SQUASHFS_CHRDEV_TYPE) 318 inode->i_mode |= S_IFCHR; 319 else 320 inode->i_mode |= S_IFBLK; 321 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 322 rdev = le32_to_cpu(sqsh_ino->rdev); 323 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); 324 325 TRACE("Device inode %x:%x, rdev %x\n", 326 SQUASHFS_INODE_BLK(ino), offset, rdev); 327 break; 328 } 329 case SQUASHFS_LBLKDEV_TYPE: 330 case SQUASHFS_LCHRDEV_TYPE: { 331 struct squashfs_ldev_inode *sqsh_ino = &squashfs_ino.ldev; 332 unsigned int rdev; 333 334 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 335 sizeof(*sqsh_ino)); 336 if (err < 0) 337 goto failed_read; 338 339 if (type == SQUASHFS_LCHRDEV_TYPE) 340 inode->i_mode |= S_IFCHR; 341 else 342 inode->i_mode |= S_IFBLK; 343 xattr_id = le32_to_cpu(sqsh_ino->xattr); 344 inode->i_op = &squashfs_inode_ops; 345 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 346 rdev = le32_to_cpu(sqsh_ino->rdev); 347 init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); 348 349 TRACE("Device inode %x:%x, rdev %x\n", 350 SQUASHFS_INODE_BLK(ino), offset, rdev); 351 break; 352 } 353 case SQUASHFS_FIFO_TYPE: 354 case SQUASHFS_SOCKET_TYPE: { 355 struct squashfs_ipc_inode *sqsh_ino = &squashfs_ino.ipc; 356 357 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 358 sizeof(*sqsh_ino)); 359 if (err < 0) 360 goto failed_read; 361 362 if (type == SQUASHFS_FIFO_TYPE) 363 inode->i_mode |= S_IFIFO; 364 else 365 inode->i_mode |= S_IFSOCK; 366 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 367 init_special_inode(inode, inode->i_mode, 0); 368 break; 369 } 370 case SQUASHFS_LFIFO_TYPE: 371 case SQUASHFS_LSOCKET_TYPE: { 372 struct squashfs_lipc_inode *sqsh_ino = &squashfs_ino.lipc; 373 374 err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset, 375 sizeof(*sqsh_ino)); 376 if (err < 0) 377 goto failed_read; 378 379 if (type == SQUASHFS_LFIFO_TYPE) 380 inode->i_mode |= S_IFIFO; 381 else 382 inode->i_mode |= S_IFSOCK; 383 xattr_id = le32_to_cpu(sqsh_ino->xattr); 384 inode->i_op = &squashfs_inode_ops; 385 set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); 386 init_special_inode(inode, inode->i_mode, 0); 387 break; 388 } 389 default: 390 ERROR("Unknown inode type %d in squashfs_iget!\n", type); 391 return -EINVAL; 392 } 393 394 if (xattr_id != SQUASHFS_INVALID_XATTR && msblk->xattr_id_table) { 395 err = squashfs_xattr_lookup(sb, xattr_id, 396 &squashfs_i(inode)->xattr_count, 397 &squashfs_i(inode)->xattr_size, 398 &squashfs_i(inode)->xattr); 399 if (err < 0) 400 goto failed_read; 401 inode->i_blocks += ((squashfs_i(inode)->xattr_size - 1) >> 9) 402 + 1; 403 } else 404 squashfs_i(inode)->xattr_count = 0; 405 406 return 0; 407 408failed_read: 409 ERROR("Unable to read inode 0x%llx\n", ino); 410 return err; 411} 412 413 414const struct inode_operations squashfs_inode_ops = { 415 .listxattr = squashfs_listxattr 416}; 417