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/cramfs_fs.h> 21 #include <linux/slab.h> 22 #include <linux/cramfs_fs_sb.h> 23 #include <linux/buffer_head.h> 24 #include <linux/vfs.h> 25 #include <asm/semaphore.h> 26 27 #include <asm/uaccess.h> 28 29 static struct super_operations cramfs_ops; 30 static struct inode_operations cramfs_dir_inode_operations; 31 static struct file_operations cramfs_directory_operations; 32 static struct address_space_operations cramfs_aops; 33 34 static DECLARE_MUTEX(read_mutex); 35 36 37 /* These two macros may change in future, to provide better st_ino 38 semantics. */ 39 #define CRAMINO(x) ((x)->offset?(x)->offset<<2:1) 40 #define OFFSET(x) ((x)->i_ino) 41 42 static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) 43 { 44 struct inode * inode = new_inode(sb); 45 static struct timespec zerotime; 46 47 if (inode) { 48 inode->i_mode = cramfs_inode->mode; 49 inode->i_uid = cramfs_inode->uid; 50 inode->i_size = cramfs_inode->size; 51 inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; 52 inode->i_blksize = PAGE_CACHE_SIZE; 53 inode->i_gid = cramfs_inode->gid; 54 /* Struct copy intentional */ 55 inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; 56 inode->i_ino = CRAMINO(cramfs_inode); 57 /* inode->i_nlink is left 1 - arguably wrong for directories, 58 but it's the best we can do without reading the directory 59 contents. 1 yields the right result in GNU find, even 60 without -noleaf option. */ 61 insert_inode_hash(inode); 62 if (S_ISREG(inode->i_mode)) { 63 inode->i_fop = &generic_ro_fops; 64 inode->i_data.a_ops = &cramfs_aops; 65 } else if (S_ISDIR(inode->i_mode)) { 66 inode->i_op = &cramfs_dir_inode_operations; 67 inode->i_fop = &cramfs_directory_operations; 68 } else if (S_ISLNK(inode->i_mode)) { 69 inode->i_op = &page_symlink_inode_operations; 70 inode->i_data.a_ops = &cramfs_aops; 71 } else { 72 inode->i_size = 0; 73 inode->i_blocks = 0; 74 init_special_inode(inode, inode->i_mode, 75 old_decode_dev(cramfs_inode->size)); 76 } 77 } 78 return inode; 79 } 80 81 /* 82 * We have our own block cache: don't fill up the buffer cache 83 * with the rom-image, because the way the filesystem is set 84 * up the accesses should be fairly regular and cached in the 85 * page cache and dentry tree anyway.. 86 * 87 * This also acts as a way to guarantee contiguous areas of up to 88 * BLKS_PER_BUF*PAGE_CACHE_SIZE, so that the caller doesn't need to 89 * worry about end-of-buffer issues even when decompressing a full 90 * page cache. 91 */ 92 #define READ_BUFFERS (2) 93 /* NEXT_BUFFER(): Loop over [0..(READ_BUFFERS-1)]. */ 94 #define NEXT_BUFFER(_ix) ((_ix) ^ 1) 95 96 /* 97 * BLKS_PER_BUF_SHIFT should be at least 2 to allow for "compressed" 98 * data that takes up more space than the original and with unlucky 99 * alignment. 100 */ 101 #define BLKS_PER_BUF_SHIFT (2) 102 #define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT) 103 #define BUFFER_SIZE (BLKS_PER_BUF*PAGE_CACHE_SIZE) 104 105 static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE]; 106 static unsigned buffer_blocknr[READ_BUFFERS]; 107 static struct super_block * buffer_dev[READ_BUFFERS]; 108 static int next_buffer; 109 110 /* 111 * Returns a pointer to a buffer containing at least LEN bytes of 112 * filesystem starting at byte offset OFFSET into the filesystem. 113 */ 114 static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) 115 { 116 struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; 117 struct page *pages[BLKS_PER_BUF]; 118 unsigned i, blocknr, buffer, unread; 119 unsigned long devsize; 120 char *data; 121 122 if (!len) 123 return NULL; 124 blocknr = offset >> PAGE_CACHE_SHIFT; 125 offset &= PAGE_CACHE_SIZE - 1; 126 127 /* Check if an existing buffer already has the data.. */ 128 for (i = 0; i < READ_BUFFERS; i++) { 129 unsigned int blk_offset; 130 131 if (buffer_dev[i] != sb) 132 continue; 133 if (blocknr < buffer_blocknr[i]) 134 continue; 135 blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_CACHE_SHIFT; 136 blk_offset += offset; 137 if (blk_offset + len > BUFFER_SIZE) 138 continue; 139 return read_buffers[i] + blk_offset; 140 } 141 142 devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT; 143 144 /* Ok, read in BLKS_PER_BUF pages completely first. */ 145 unread = 0; 146 for (i = 0; i < BLKS_PER_BUF; i++) { 147 struct page *page = NULL; 148 149 if (blocknr + i < devsize) { 150 page = read_cache_page(mapping, blocknr + i, 151 (filler_t *)mapping->a_ops->readpage, 152 NULL); 153 /* synchronous error? */ 154 if (IS_ERR(page)) 155 page = NULL; 156 } 157 pages[i] = page; 158 } 159 160 for (i = 0; i < BLKS_PER_BUF; i++) { 161 struct page *page = pages[i]; 162 if (page) { 163 wait_on_page_locked(page); 164 if (!PageUptodate(page)) { 165 /* asynchronous error */ 166 page_cache_release(page); 167 pages[i] = NULL; 168 } 169 } 170 } 171 172 buffer = next_buffer; 173 next_buffer = NEXT_BUFFER(buffer); 174 buffer_blocknr[buffer] = blocknr; 175 buffer_dev[buffer] = sb; 176 177 data = read_buffers[buffer]; 178 for (i = 0; i < BLKS_PER_BUF; i++) { 179 struct page *page = pages[i]; 180 if (page) { 181 memcpy(data, kmap(page), PAGE_CACHE_SIZE); 182 kunmap(page); 183 page_cache_release(page); 184 } else 185 memset(data, 0, PAGE_CACHE_SIZE); 186 data += PAGE_CACHE_SIZE; 187 } 188 return read_buffers[buffer] + offset; 189 } 190 191 static void cramfs_put_super(struct super_block *sb) 192 { 193 kfree(sb->s_fs_info); 194 sb->s_fs_info = NULL; 195 } 196 197 static int cramfs_remount(struct super_block *sb, int *flags, char *data) 198 { 199 *flags |= MS_RDONLY; 200 return 0; 201 } 202 203 static int cramfs_fill_super(struct super_block *sb, void *data, int silent) 204 { 205 int i; 206 struct cramfs_super super; 207 unsigned long root_offset; 208 struct cramfs_sb_info *sbi; 209 struct inode *root; 210 211 sb->s_flags |= MS_RDONLY; 212 213 sbi = kmalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); 214 if (!sbi) 215 return -ENOMEM; 216 sb->s_fs_info = sbi; 217 memset(sbi, 0, sizeof(struct cramfs_sb_info)); 218 219 /* Invalidate the read buffers on mount: think disk change.. */ 220 down(&read_mutex); 221 for (i = 0; i < READ_BUFFERS; i++) 222 buffer_blocknr[i] = -1; 223 224 /* Read the first block and get the superblock from it */ 225 memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super)); 226 up(&read_mutex); 227 228 /* Do sanity checks on the superblock */ 229 if (super.magic != CRAMFS_MAGIC) { 230 /* check at 512 byte offset */ 231 down(&read_mutex); 232 memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super)); 233 up(&read_mutex); 234 if (super.magic != CRAMFS_MAGIC) { 235 if (!silent) 236 printk(KERN_ERR "cramfs: wrong magic\n"); 237 goto out; 238 } 239 } 240 241 /* get feature flags first */ 242 if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { 243 printk(KERN_ERR "cramfs: unsupported filesystem features\n"); 244 goto out; 245 } 246 247 /* Check that the root inode is in a sane state */ 248 if (!S_ISDIR(super.root.mode)) { 249 printk(KERN_ERR "cramfs: root is not a directory\n"); 250 goto out; 251 } 252 root_offset = super.root.offset << 2; 253 if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) { 254 sbi->size=super.size; 255 sbi->blocks=super.fsid.blocks; 256 sbi->files=super.fsid.files; 257 } else { 258 sbi->size=1<<28; 259 sbi->blocks=0; 260 sbi->files=0; 261 } 262 sbi->magic=super.magic; 263 sbi->flags=super.flags; 264 if (root_offset == 0) 265 printk(KERN_INFO "cramfs: empty filesystem"); 266 else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && 267 ((root_offset != sizeof(struct cramfs_super)) && 268 (root_offset != 512 + sizeof(struct cramfs_super)))) 269 { 270 printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); 271 goto out; 272 } 273 274 /* Set it all up.. */ 275 sb->s_op = &cramfs_ops; 276 root = get_cramfs_inode(sb, &super.root); 277 if (!root) 278 goto out; 279 sb->s_root = d_alloc_root(root); 280 if (!sb->s_root) { 281 iput(root); 282 goto out; 283 } 284 return 0; 285 out: 286 kfree(sbi); 287 sb->s_fs_info = NULL; 288 return -EINVAL; 289 } 290 291 static int cramfs_statfs(struct super_block *sb, struct kstatfs *buf) 292 { 293 buf->f_type = CRAMFS_MAGIC; 294 buf->f_bsize = PAGE_CACHE_SIZE; 295 buf->f_blocks = CRAMFS_SB(sb)->blocks; 296 buf->f_bfree = 0; 297 buf->f_bavail = 0; 298 buf->f_files = CRAMFS_SB(sb)->files; 299 buf->f_ffree = 0; 300 buf->f_namelen = CRAMFS_MAXPATHLEN; 301 return 0; 302 } 303 304 /* 305 * Read a cramfs directory entry. 306 */ 307 static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 308 { 309 struct inode *inode = filp->f_dentry->d_inode; 310 struct super_block *sb = inode->i_sb; 311 char *buf; 312 unsigned int offset; 313 int copied; 314 315 /* Offset within the thing. */ 316 offset = filp->f_pos; 317 if (offset >= inode->i_size) 318 return 0; 319 /* Directory entries are always 4-byte aligned */ 320 if (offset & 3) 321 return -EINVAL; 322 323 buf = kmalloc(256, GFP_KERNEL); 324 if (!buf) 325 return -ENOMEM; 326 327 copied = 0; 328 while (offset < inode->i_size) { 329 struct cramfs_inode *de; 330 unsigned long nextoffset; 331 char *name; 332 ino_t ino; 333 mode_t mode; 334 int namelen, error; 335 336 down(&read_mutex); 337 de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256); 338 name = (char *)(de+1); 339 340 /* 341 * Namelengths on disk are shifted by two 342 * and the name padded out to 4-byte boundaries 343 * with zeroes. 344 */ 345 namelen = de->namelen << 2; 346 memcpy(buf, name, namelen); 347 ino = CRAMINO(de); 348 mode = de->mode; 349 up(&read_mutex); 350 nextoffset = offset + sizeof(*de) + namelen; 351 for (;;) { 352 if (!namelen) { 353 kfree(buf); 354 return -EIO; 355 } 356 if (buf[namelen-1]) 357 break; 358 namelen--; 359 } 360 error = filldir(dirent, buf, namelen, offset, ino, mode >> 12); 361 if (error) 362 break; 363 364 offset = nextoffset; 365 filp->f_pos = offset; 366 copied++; 367 } 368 kfree(buf); 369 return 0; 370 } 371 372 /* 373 * Lookup and fill in the inode data.. 374 */ 375 static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 376 { 377 unsigned int offset = 0; 378 int sorted; 379 380 down(&read_mutex); 381 sorted = CRAMFS_SB(dir->i_sb)->flags & CRAMFS_FLAG_SORTED_DIRS; 382 while (offset < dir->i_size) { 383 struct cramfs_inode *de; 384 char *name; 385 int namelen, retval; 386 387 de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256); 388 name = (char *)(de+1); 389 390 /* Try to take advantage of sorted directories */ 391 if (sorted && (dentry->d_name.name[0] < name[0])) 392 break; 393 394 namelen = de->namelen << 2; 395 offset += sizeof(*de) + namelen; 396 397 /* Quick check that the name is roughly the right length */ 398 if (((dentry->d_name.len + 3) & ~3) != namelen) 399 continue; 400 401 for (;;) { 402 if (!namelen) { 403 up(&read_mutex); 404 return ERR_PTR(-EIO); 405 } 406 if (name[namelen-1]) 407 break; 408 namelen--; 409 } 410 if (namelen != dentry->d_name.len) 411 continue; 412 retval = memcmp(dentry->d_name.name, name, namelen); 413 if (retval > 0) 414 continue; 415 if (!retval) { 416 struct cramfs_inode entry = *de; 417 up(&read_mutex); 418 d_add(dentry, get_cramfs_inode(dir->i_sb, &entry)); 419 return NULL; 420 } 421 /* else (retval < 0) */ 422 if (sorted) 423 break; 424 } 425 up(&read_mutex); 426 d_add(dentry, NULL); 427 return NULL; 428 } 429 430 static int cramfs_readpage(struct file *file, struct page * page) 431 { 432 struct inode *inode = page->mapping->host; 433 u32 maxblock, bytes_filled; 434 void *pgdata; 435 436 maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 437 bytes_filled = 0; 438 if (page->index < maxblock) { 439 struct super_block *sb = inode->i_sb; 440 u32 blkptr_offset = OFFSET(inode) + page->index*4; 441 u32 start_offset, compr_len; 442 443 start_offset = OFFSET(inode) + maxblock*4; 444 down(&read_mutex); 445 if (page->index) 446 start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4); 447 compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4) - start_offset); 448 up(&read_mutex); 449 pgdata = kmap(page); 450 if (compr_len == 0) 451 ; /* hole */ 452 else { 453 down(&read_mutex); 454 bytes_filled = cramfs_uncompress_block(pgdata, 455 PAGE_CACHE_SIZE, 456 cramfs_read(sb, start_offset, compr_len), 457 compr_len); 458 up(&read_mutex); 459 } 460 } else 461 pgdata = kmap(page); 462 memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); 463 kunmap(page); 464 flush_dcache_page(page); 465 SetPageUptodate(page); 466 unlock_page(page); 467 return 0; 468 } 469 470 static struct address_space_operations cramfs_aops = { 471 .readpage = cramfs_readpage 472 }; 473 474 /* 475 * Our operations: 476 */ 477 478 /* 479 * A directory can only readdir 480 */ 481 static struct file_operations cramfs_directory_operations = { 482 .llseek = generic_file_llseek, 483 .read = generic_read_dir, 484 .readdir = cramfs_readdir, 485 }; 486 487 static struct inode_operations cramfs_dir_inode_operations = { 488 .lookup = cramfs_lookup, 489 }; 490 491 static struct super_operations cramfs_ops = { 492 .put_super = cramfs_put_super, 493 .remount_fs = cramfs_remount, 494 .statfs = cramfs_statfs, 495 }; 496 497 static struct super_block *cramfs_get_sb(struct file_system_type *fs_type, 498 int flags, const char *dev_name, void *data) 499 { 500 return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super); 501 } 502 503 static struct file_system_type cramfs_fs_type = { 504 .owner = THIS_MODULE, 505 .name = "cramfs", 506 .get_sb = cramfs_get_sb, 507 .kill_sb = kill_block_super, 508 .fs_flags = FS_REQUIRES_DEV, 509 }; 510 511 static int __init init_cramfs_fs(void) 512 { 513 cramfs_uncompress_init(); 514 return register_filesystem(&cramfs_fs_type); 515 } 516 517 static void __exit exit_cramfs_fs(void) 518 { 519 cramfs_uncompress_exit(); 520 unregister_filesystem(&cramfs_fs_type); 521 } 522 523 module_init(init_cramfs_fs) 524 module_exit(exit_cramfs_fs) 525 MODULE_LICENSE("GPL"); 526