1 /* 2 * Compressed rom filesystem for Linux. 3 * 4 * Copyright (C) 1999 Linus Torvalds. 5 * 6 * This file is released under the GPL. 7 */ 8 9 /* 10 * These are the VFS interfaces to the compressed rom filesystem. 11 * The actual compression is based on zlib, see the other files. 12 */ 13 14 #include <linux/module.h> 15 #include <linux/fs.h> 16 #include <linux/pagemap.h> 17 #include <linux/init.h> 18 #include <linux/string.h> 19 #include <linux/blkdev.h> 20 #include <linux/slab.h> 21 #include <linux/vfs.h> 22 #include <linux/mutex.h> 23 #include <uapi/linux/cramfs_fs.h> 24 #include <asm/uaccess.h> 25 26 #include "internal.h" 27 28 /* 29 * cramfs super-block data in memory 30 */ 31 struct cramfs_sb_info { 32 unsigned long magic; 33 unsigned long size; 34 unsigned long blocks; 35 unsigned long files; 36 unsigned long flags; 37 }; 38 39 static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb) 40 { 41 return sb->s_fs_info; 42 } 43 44 static const struct super_operations cramfs_ops; 45 static const struct inode_operations cramfs_dir_inode_operations; 46 static const struct file_operations cramfs_directory_operations; 47 static const struct address_space_operations cramfs_aops; 48 49 static DEFINE_MUTEX(read_mutex); 50 51 52 /* These macros may change in future, to provide better st_ino semantics. */ 53 #define OFFSET(x) ((x)->i_ino) 54 55 static unsigned long cramino(const struct cramfs_inode *cino, unsigned int offset) 56 { 57 if (!cino->offset) 58 return offset + 1; 59 if (!cino->size) 60 return offset + 1; 61 62 /* 63 * The file mode test fixes buggy mkcramfs implementations where 64 * cramfs_inode->offset is set to a non zero value for entries 65 * which did not contain data, like devices node and fifos. 66 */ 67 switch (cino->mode & S_IFMT) { 68 case S_IFREG: 69 case S_IFDIR: 70 case S_IFLNK: 71 return cino->offset << 2; 72 default: 73 break; 74 } 75 return offset + 1; 76 } 77 78 static struct inode *get_cramfs_inode(struct super_block *sb, 79 const struct cramfs_inode *cramfs_inode, unsigned int offset) 80 { 81 struct inode *inode; 82 static struct timespec zerotime; 83 84 inode = iget_locked(sb, cramino(cramfs_inode, offset)); 85 if (!inode) 86 return ERR_PTR(-ENOMEM); 87 if (!(inode->i_state & I_NEW)) 88 return inode; 89 90 switch (cramfs_inode->mode & S_IFMT) { 91 case S_IFREG: 92 inode->i_fop = &generic_ro_fops; 93 inode->i_data.a_ops = &cramfs_aops; 94 break; 95 case S_IFDIR: 96 inode->i_op = &cramfs_dir_inode_operations; 97 inode->i_fop = &cramfs_directory_operations; 98 break; 99 case S_IFLNK: 100 inode->i_op = &page_symlink_inode_operations; 101 inode->i_data.a_ops = &cramfs_aops; 102 break; 103 default: 104 init_special_inode(inode, cramfs_inode->mode, 105 old_decode_dev(cramfs_inode->size)); 106 } 107 108 inode->i_mode = cramfs_inode->mode; 109 i_uid_write(inode, cramfs_inode->uid); 110 i_gid_write(inode, cramfs_inode->gid); 111 112 /* if the lower 2 bits are zero, the inode contains data */ 113 if (!(inode->i_ino & 3)) { 114 inode->i_size = cramfs_inode->size; 115 inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; 116 } 117 118 /* Struct copy intentional */ 119 inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; 120 /* inode->i_nlink is left 1 - arguably wrong for directories, 121 but it's the best we can do without reading the directory 122 contents. 1 yields the right result in GNU find, even 123 without -noleaf option. */ 124 125 unlock_new_inode(inode); 126 127 return inode; 128 } 129 130 /* 131 * We have our own block cache: don't fill up the buffer cache 132 * with the rom-image, because the way the filesystem is set 133 * up the accesses should be fairly regular and cached in the 134 * page cache and dentry tree anyway.. 135 * 136 * This also acts as a way to guarantee contiguous areas of up to 137 * BLKS_PER_BUF*PAGE_CACHE_SIZE, so that the caller doesn't need to 138 * worry about end-of-buffer issues even when decompressing a full 139 * page cache. 140 */ 141 #define READ_BUFFERS (2) 142 /* NEXT_BUFFER(): Loop over [0..(READ_BUFFERS-1)]. */ 143 #define NEXT_BUFFER(_ix) ((_ix) ^ 1) 144 145 /* 146 * BLKS_PER_BUF_SHIFT should be at least 2 to allow for "compressed" 147 * data that takes up more space than the original and with unlucky 148 * alignment. 149 */ 150 #define BLKS_PER_BUF_SHIFT (2) 151 #define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT) 152 #define BUFFER_SIZE (BLKS_PER_BUF*PAGE_CACHE_SIZE) 153 154 static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE]; 155 static unsigned buffer_blocknr[READ_BUFFERS]; 156 static struct super_block * buffer_dev[READ_BUFFERS]; 157 static int next_buffer; 158 159 /* 160 * Returns a pointer to a buffer containing at least LEN bytes of 161 * filesystem starting at byte offset OFFSET into the filesystem. 162 */ 163 static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) 164 { 165 struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; 166 struct page *pages[BLKS_PER_BUF]; 167 unsigned i, blocknr, buffer; 168 unsigned long devsize; 169 char *data; 170 171 if (!len) 172 return NULL; 173 blocknr = offset >> PAGE_CACHE_SHIFT; 174 offset &= PAGE_CACHE_SIZE - 1; 175 176 /* Check if an existing buffer already has the data.. */ 177 for (i = 0; i < READ_BUFFERS; i++) { 178 unsigned int blk_offset; 179 180 if (buffer_dev[i] != sb) 181 continue; 182 if (blocknr < buffer_blocknr[i]) 183 continue; 184 blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_CACHE_SHIFT; 185 blk_offset += offset; 186 if (blk_offset + len > BUFFER_SIZE) 187 continue; 188 return read_buffers[i] + blk_offset; 189 } 190 191 devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT; 192 193 /* Ok, read in BLKS_PER_BUF pages completely first. */ 194 for (i = 0; i < BLKS_PER_BUF; i++) { 195 struct page *page = NULL; 196 197 if (blocknr + i < devsize) { 198 page = read_mapping_page_async(mapping, blocknr + i, 199 NULL); 200 /* synchronous error? */ 201 if (IS_ERR(page)) 202 page = NULL; 203 } 204 pages[i] = page; 205 } 206 207 for (i = 0; i < BLKS_PER_BUF; i++) { 208 struct page *page = pages[i]; 209 if (page) { 210 wait_on_page_locked(page); 211 if (!PageUptodate(page)) { 212 /* asynchronous error */ 213 page_cache_release(page); 214 pages[i] = NULL; 215 } 216 } 217 } 218 219 buffer = next_buffer; 220 next_buffer = NEXT_BUFFER(buffer); 221 buffer_blocknr[buffer] = blocknr; 222 buffer_dev[buffer] = sb; 223 224 data = read_buffers[buffer]; 225 for (i = 0; i < BLKS_PER_BUF; i++) { 226 struct page *page = pages[i]; 227 if (page) { 228 memcpy(data, kmap(page), PAGE_CACHE_SIZE); 229 kunmap(page); 230 page_cache_release(page); 231 } else 232 memset(data, 0, PAGE_CACHE_SIZE); 233 data += PAGE_CACHE_SIZE; 234 } 235 return read_buffers[buffer] + offset; 236 } 237 238 static void cramfs_kill_sb(struct super_block *sb) 239 { 240 struct cramfs_sb_info *sbi = CRAMFS_SB(sb); 241 kill_block_super(sb); 242 kfree(sbi); 243 } 244 245 static int cramfs_remount(struct super_block *sb, int *flags, char *data) 246 { 247 *flags |= MS_RDONLY; 248 return 0; 249 } 250 251 static int cramfs_fill_super(struct super_block *sb, void *data, int silent) 252 { 253 int i; 254 struct cramfs_super super; 255 unsigned long root_offset; 256 struct cramfs_sb_info *sbi; 257 struct inode *root; 258 259 sb->s_flags |= MS_RDONLY; 260 261 sbi = kzalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); 262 if (!sbi) 263 return -ENOMEM; 264 sb->s_fs_info = sbi; 265 266 /* Invalidate the read buffers on mount: think disk change.. */ 267 mutex_lock(&read_mutex); 268 for (i = 0; i < READ_BUFFERS; i++) 269 buffer_blocknr[i] = -1; 270 271 /* Read the first block and get the superblock from it */ 272 memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super)); 273 mutex_unlock(&read_mutex); 274 275 /* Do sanity checks on the superblock */ 276 if (super.magic != CRAMFS_MAGIC) { 277 /* check for wrong endianness */ 278 if (super.magic == CRAMFS_MAGIC_WEND) { 279 if (!silent) 280 printk(KERN_ERR "cramfs: wrong endianness\n"); 281 return -EINVAL; 282 } 283 284 /* check at 512 byte offset */ 285 mutex_lock(&read_mutex); 286 memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super)); 287 mutex_unlock(&read_mutex); 288 if (super.magic != CRAMFS_MAGIC) { 289 if (super.magic == CRAMFS_MAGIC_WEND && !silent) 290 printk(KERN_ERR "cramfs: wrong endianness\n"); 291 else if (!silent) 292 printk(KERN_ERR "cramfs: wrong magic\n"); 293 return -EINVAL; 294 } 295 } 296 297 /* get feature flags first */ 298 if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { 299 printk(KERN_ERR "cramfs: unsupported filesystem features\n"); 300 return -EINVAL; 301 } 302 303 /* Check that the root inode is in a sane state */ 304 if (!S_ISDIR(super.root.mode)) { 305 printk(KERN_ERR "cramfs: root is not a directory\n"); 306 return -EINVAL; 307 } 308 /* correct strange, hard-coded permissions of mkcramfs */ 309 super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 310 311 root_offset = super.root.offset << 2; 312 if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { 313 sbi->size=super.size; 314 sbi->blocks=super.fsid.blocks; 315 sbi->files=super.fsid.files; 316 } else { 317 sbi->size=1<<28; 318 sbi->blocks=0; 319 sbi->files=0; 320 } 321 sbi->magic=super.magic; 322 sbi->flags=super.flags; 323 if (root_offset == 0) 324 printk(KERN_INFO "cramfs: empty filesystem"); 325 else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && 326 ((root_offset != sizeof(struct cramfs_super)) && 327 (root_offset != 512 + sizeof(struct cramfs_super)))) 328 { 329 printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); 330 return -EINVAL; 331 } 332 333 /* Set it all up.. */ 334 sb->s_op = &cramfs_ops; 335 root = get_cramfs_inode(sb, &super.root, 0); 336 if (IS_ERR(root)) 337 return PTR_ERR(root); 338 sb->s_root = d_make_root(root); 339 if (!sb->s_root) 340 return -ENOMEM; 341 return 0; 342 } 343 344 static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) 345 { 346 struct super_block *sb = dentry->d_sb; 347 u64 id = huge_encode_dev(sb->s_bdev->bd_dev); 348 349 buf->f_type = CRAMFS_MAGIC; 350 buf->f_bsize = PAGE_CACHE_SIZE; 351 buf->f_blocks = CRAMFS_SB(sb)->blocks; 352 buf->f_bfree = 0; 353 buf->f_bavail = 0; 354 buf->f_files = CRAMFS_SB(sb)->files; 355 buf->f_ffree = 0; 356 buf->f_fsid.val[0] = (u32)id; 357 buf->f_fsid.val[1] = (u32)(id >> 32); 358 buf->f_namelen = CRAMFS_MAXPATHLEN; 359 return 0; 360 } 361 362 /* 363 * Read a cramfs directory entry. 364 */ 365 static int cramfs_readdir(struct file *file, struct dir_context *ctx) 366 { 367 struct inode *inode = file_inode(file); 368 struct super_block *sb = inode->i_sb; 369 char *buf; 370 unsigned int offset; 371 372 /* Offset within the thing. */ 373 if (ctx->pos >= inode->i_size) 374 return 0; 375 offset = ctx->pos; 376 /* Directory entries are always 4-byte aligned */ 377 if (offset & 3) 378 return -EINVAL; 379 380 buf = kmalloc(CRAMFS_MAXPATHLEN, GFP_KERNEL); 381 if (!buf) 382 return -ENOMEM; 383 384 while (offset < inode->i_size) { 385 struct cramfs_inode *de; 386 unsigned long nextoffset; 387 char *name; 388 ino_t ino; 389 umode_t mode; 390 int namelen; 391 392 mutex_lock(&read_mutex); 393 de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); 394 name = (char *)(de+1); 395 396 /* 397 * Namelengths on disk are shifted by two 398 * and the name padded out to 4-byte boundaries 399 * with zeroes. 400 */ 401 namelen = de->namelen << 2; 402 memcpy(buf, name, namelen); 403 ino = cramino(de, OFFSET(inode) + offset); 404 mode = de->mode; 405 mutex_unlock(&read_mutex); 406 nextoffset = offset + sizeof(*de) + namelen; 407 for (;;) { 408 if (!namelen) { 409 kfree(buf); 410 return -EIO; 411 } 412 if (buf[namelen-1]) 413 break; 414 namelen--; 415 } 416 if (!dir_emit(ctx, buf, namelen, ino, mode >> 12)) 417 break; 418 419 ctx->pos = offset = nextoffset; 420 } 421 kfree(buf); 422 return 0; 423 } 424 425 /* 426 * Lookup and fill in the inode data.. 427 */ 428 static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) 429 { 430 unsigned int offset = 0; 431 struct inode *inode = NULL; 432 int sorted; 433 434 mutex_lock(&read_mutex); 435 sorted = CRAMFS_SB(dir->i_sb)->flags & CRAMFS_FLAG_SORTED_DIRS; 436 while (offset < dir->i_size) { 437 struct cramfs_inode *de; 438 char *name; 439 int namelen, retval; 440 int dir_off = OFFSET(dir) + offset; 441 442 de = cramfs_read(dir->i_sb, dir_off, sizeof(*de)+CRAMFS_MAXPATHLEN); 443 name = (char *)(de+1); 444 445 /* Try to take advantage of sorted directories */ 446 if (sorted && (dentry->d_name.name[0] < name[0])) 447 break; 448 449 namelen = de->namelen << 2; 450 offset += sizeof(*de) + namelen; 451 452 /* Quick check that the name is roughly the right length */ 453 if (((dentry->d_name.len + 3) & ~3) != namelen) 454 continue; 455 456 for (;;) { 457 if (!namelen) { 458 inode = ERR_PTR(-EIO); 459 goto out; 460 } 461 if (name[namelen-1]) 462 break; 463 namelen--; 464 } 465 if (namelen != dentry->d_name.len) 466 continue; 467 retval = memcmp(dentry->d_name.name, name, namelen); 468 if (retval > 0) 469 continue; 470 if (!retval) { 471 inode = get_cramfs_inode(dir->i_sb, de, dir_off); 472 break; 473 } 474 /* else (retval < 0) */ 475 if (sorted) 476 break; 477 } 478 out: 479 mutex_unlock(&read_mutex); 480 if (IS_ERR(inode)) 481 return ERR_CAST(inode); 482 d_add(dentry, inode); 483 return NULL; 484 } 485 486 static int cramfs_readpage(struct file *file, struct page * page) 487 { 488 struct inode *inode = page->mapping->host; 489 u32 maxblock; 490 int bytes_filled; 491 void *pgdata; 492 493 maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 494 bytes_filled = 0; 495 pgdata = kmap(page); 496 497 if (page->index < maxblock) { 498 struct super_block *sb = inode->i_sb; 499 u32 blkptr_offset = OFFSET(inode) + page->index*4; 500 u32 start_offset, compr_len; 501 502 start_offset = OFFSET(inode) + maxblock*4; 503 mutex_lock(&read_mutex); 504 if (page->index) 505 start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 506 4); 507 compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - 508 start_offset); 509 mutex_unlock(&read_mutex); 510 511 if (compr_len == 0) 512 ; /* hole */ 513 else if (unlikely(compr_len > (PAGE_CACHE_SIZE << 1))) { 514 pr_err("cramfs: bad compressed blocksize %u\n", 515 compr_len); 516 goto err; 517 } else { 518 mutex_lock(&read_mutex); 519 bytes_filled = cramfs_uncompress_block(pgdata, 520 PAGE_CACHE_SIZE, 521 cramfs_read(sb, start_offset, compr_len), 522 compr_len); 523 mutex_unlock(&read_mutex); 524 if (unlikely(bytes_filled < 0)) 525 goto err; 526 } 527 } 528 529 memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); 530 flush_dcache_page(page); 531 kunmap(page); 532 SetPageUptodate(page); 533 unlock_page(page); 534 return 0; 535 536 err: 537 kunmap(page); 538 ClearPageUptodate(page); 539 SetPageError(page); 540 unlock_page(page); 541 return 0; 542 } 543 544 static const struct address_space_operations cramfs_aops = { 545 .readpage = cramfs_readpage 546 }; 547 548 /* 549 * Our operations: 550 */ 551 552 /* 553 * A directory can only readdir 554 */ 555 static const struct file_operations cramfs_directory_operations = { 556 .llseek = generic_file_llseek, 557 .read = generic_read_dir, 558 .iterate = cramfs_readdir, 559 }; 560 561 static const struct inode_operations cramfs_dir_inode_operations = { 562 .lookup = cramfs_lookup, 563 }; 564 565 static const struct super_operations cramfs_ops = { 566 .remount_fs = cramfs_remount, 567 .statfs = cramfs_statfs, 568 }; 569 570 static struct dentry *cramfs_mount(struct file_system_type *fs_type, 571 int flags, const char *dev_name, void *data) 572 { 573 return mount_bdev(fs_type, flags, dev_name, data, cramfs_fill_super); 574 } 575 576 static struct file_system_type cramfs_fs_type = { 577 .owner = THIS_MODULE, 578 .name = "cramfs", 579 .mount = cramfs_mount, 580 .kill_sb = cramfs_kill_sb, 581 .fs_flags = FS_REQUIRES_DEV, 582 }; 583 MODULE_ALIAS_FS("cramfs"); 584 585 static int __init init_cramfs_fs(void) 586 { 587 int rv; 588 589 rv = cramfs_uncompress_init(); 590 if (rv < 0) 591 return rv; 592 rv = register_filesystem(&cramfs_fs_type); 593 if (rv < 0) 594 cramfs_uncompress_exit(); 595 return rv; 596 } 597 598 static void __exit exit_cramfs_fs(void) 599 { 600 cramfs_uncompress_exit(); 601 unregister_filesystem(&cramfs_fs_type); 602 } 603 604 module_init(init_cramfs_fs) 605 module_exit(exit_cramfs_fs) 606 MODULE_LICENSE("GPL"); 607