/* Block- or MTD-based romfs * * Copyright © 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells ([email protected]) * * Derived from: ROMFS file system, Linux implementation * * Copyright © 1997-1999 Janos Farkas <[email protected]> * * Using parts of the minix filesystem * Copyright © 1991, 1992 Linus Torvalds * * and parts of the affs filesystem additionally * Copyright © 1993 Ray Burr * Copyright © 1996 Hans-Joachim Widmaier * * Changes * Changed for 2.1.19 modules * Jan 1997 Initial release * Jun 1997 2.1.43+ changes * Proper page locking in read_folio * Changed to work with 2.1.45+ fs * Jul 1997 Fixed follow_link * 2.1.47 * lookup shouldn't return -ENOENT * from Horst von Brand: * fail on wrong checksum * double unlock_super was possible * correct namelen for statfs * spotted by Bill Hawes: * readlink shouldn't iput() * Jun 1998 2.1.106 from Avery Pennarun: glibc scandir() * exposed a problem in readdir * 2.1.107 code-freeze spellchecker run * Aug 1998 2.1.118+ VFS changes * Sep 1998 2.1.122 another VFS change (follow_link) * Apr 1999 2.2.7 no more EBADF checking in * lookup/readdir, use ERR_PTR * Jun 1999 2.3.6 d_alloc_root use changed * 2.3.9 clean up usage of ENOENT/negative * dentries in lookup * clean up page flags setting * (error, uptodate, locking) in * in read_folio * use init_special_inode for * fifos/sockets (and streamline) in * read_inode, fix _ops table order * Aug 1999 2.3.16 __initfunc() => __init change * Oct 1999 2.3.24 page->owner hack obsoleted * Nov 1999 2.3.27 2.3.25+ page->offset => index change * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version * 2 of the Licence, or (at your option) any later version. */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/string.h> #include <linux/fs.h> #include <linux/time.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/blkdev.h> #include <linux/fs_context.h> #include <linux/mount.h> #include <linux/namei.h> #include <linux/statfs.h> #include <linux/mtd/super.h> #include <linux/ctype.h> #include <linux/highmem.h> #include <linux/pagemap.h> #include <linux/uaccess.h> #include <linux/major.h> #include "internal.h" static struct kmem_cache *romfs_inode_cachep; static const umode_t romfs_modemap[8] = …; static const unsigned char romfs_dtype_table[] = …; static struct inode *romfs_iget(struct super_block *sb, unsigned long pos); /* * read a page worth of data from the image */ static int romfs_read_folio(struct file *file, struct folio *folio) { … } static const struct address_space_operations romfs_aops = …; /* * read the entries from a directory */ static int romfs_readdir(struct file *file, struct dir_context *ctx) { … } /* * look up an entry in a directory */ static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { … } static const struct file_operations romfs_dir_operations = …; static const struct inode_operations romfs_dir_inode_operations = …; /* * get a romfs inode based on its position in the image (which doubles as the * inode number) */ static struct inode *romfs_iget(struct super_block *sb, unsigned long pos) { … } /* * allocate a new inode */ static struct inode *romfs_alloc_inode(struct super_block *sb) { … } /* * return a spent inode to the slab cache */ static void romfs_free_inode(struct inode *inode) { … } /* * get filesystem statistics */ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf) { … } /* * remounting must involve read-only */ static int romfs_reconfigure(struct fs_context *fc) { … } static const struct super_operations romfs_super_ops = …; /* * checksum check on part of a romfs filesystem */ static __u32 romfs_checksum(const void *data, int size) { … } /* * fill in the superblock */ static int romfs_fill_super(struct super_block *sb, struct fs_context *fc) { … } /* * get a superblock for mounting */ static int romfs_get_tree(struct fs_context *fc) { … } static const struct fs_context_operations romfs_context_ops = …; /* * Set up the filesystem mount context. */ static int romfs_init_fs_context(struct fs_context *fc) { … } /* * destroy a romfs superblock in the appropriate manner */ static void romfs_kill_sb(struct super_block *sb) { … } static struct file_system_type romfs_fs_type = …; MODULE_ALIAS_FS(…) …; /* * inode storage initialiser */ static void romfs_i_init_once(void *_inode) { … } /* * romfs module initialisation */ static int __init init_romfs_fs(void) { … } /* * romfs module removal */ static void __exit exit_romfs_fs(void) { … } module_init(…) …; module_exit(exit_romfs_fs); MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …; /* Actually dual-licensed, but it doesn't matter for */