cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inode.c (7270B)


      1/*
      2 * Resizable simple ram filesystem for Linux.
      3 *
      4 * Copyright (C) 2000 Linus Torvalds.
      5 *               2000 Transmeta Corp.
      6 *
      7 * Usage limits added by David Gibson, Linuxcare Australia.
      8 * This file is released under the GPL.
      9 */
     10
     11/*
     12 * NOTE! This filesystem is probably most useful
     13 * not as a real filesystem, but as an example of
     14 * how virtual filesystems can be written.
     15 *
     16 * It doesn't get much simpler than this. Consider
     17 * that this file implements the full semantics of
     18 * a POSIX-compliant read-write filesystem.
     19 *
     20 * Note in particular how the filesystem does not
     21 * need to implement any data structures of its own
     22 * to keep track of the virtual data: using the VFS
     23 * caches is sufficient.
     24 */
     25
     26#include <linux/fs.h>
     27#include <linux/pagemap.h>
     28#include <linux/highmem.h>
     29#include <linux/time.h>
     30#include <linux/init.h>
     31#include <linux/string.h>
     32#include <linux/backing-dev.h>
     33#include <linux/ramfs.h>
     34#include <linux/sched.h>
     35#include <linux/parser.h>
     36#include <linux/magic.h>
     37#include <linux/slab.h>
     38#include <linux/uaccess.h>
     39#include <linux/fs_context.h>
     40#include <linux/fs_parser.h>
     41#include <linux/seq_file.h>
     42#include "internal.h"
     43
     44struct ramfs_mount_opts {
     45	umode_t mode;
     46};
     47
     48struct ramfs_fs_info {
     49	struct ramfs_mount_opts mount_opts;
     50};
     51
     52#define RAMFS_DEFAULT_MODE	0755
     53
     54static const struct super_operations ramfs_ops;
     55static const struct inode_operations ramfs_dir_inode_operations;
     56
     57struct inode *ramfs_get_inode(struct super_block *sb,
     58				const struct inode *dir, umode_t mode, dev_t dev)
     59{
     60	struct inode * inode = new_inode(sb);
     61
     62	if (inode) {
     63		inode->i_ino = get_next_ino();
     64		inode_init_owner(&init_user_ns, inode, dir, mode);
     65		inode->i_mapping->a_ops = &ram_aops;
     66		mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
     67		mapping_set_unevictable(inode->i_mapping);
     68		inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
     69		switch (mode & S_IFMT) {
     70		default:
     71			init_special_inode(inode, mode, dev);
     72			break;
     73		case S_IFREG:
     74			inode->i_op = &ramfs_file_inode_operations;
     75			inode->i_fop = &ramfs_file_operations;
     76			break;
     77		case S_IFDIR:
     78			inode->i_op = &ramfs_dir_inode_operations;
     79			inode->i_fop = &simple_dir_operations;
     80
     81			/* directory inodes start off with i_nlink == 2 (for "." entry) */
     82			inc_nlink(inode);
     83			break;
     84		case S_IFLNK:
     85			inode->i_op = &page_symlink_inode_operations;
     86			inode_nohighmem(inode);
     87			break;
     88		}
     89	}
     90	return inode;
     91}
     92
     93/*
     94 * File creation. Allocate an inode, and we're done..
     95 */
     96/* SMP-safe */
     97static int
     98ramfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
     99	    struct dentry *dentry, umode_t mode, dev_t dev)
    100{
    101	struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev);
    102	int error = -ENOSPC;
    103
    104	if (inode) {
    105		d_instantiate(dentry, inode);
    106		dget(dentry);	/* Extra count - pin the dentry in core */
    107		error = 0;
    108		dir->i_mtime = dir->i_ctime = current_time(dir);
    109	}
    110	return error;
    111}
    112
    113static int ramfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
    114		       struct dentry *dentry, umode_t mode)
    115{
    116	int retval = ramfs_mknod(&init_user_ns, dir, dentry, mode | S_IFDIR, 0);
    117	if (!retval)
    118		inc_nlink(dir);
    119	return retval;
    120}
    121
    122static int ramfs_create(struct user_namespace *mnt_userns, struct inode *dir,
    123			struct dentry *dentry, umode_t mode, bool excl)
    124{
    125	return ramfs_mknod(&init_user_ns, dir, dentry, mode | S_IFREG, 0);
    126}
    127
    128static int ramfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
    129			 struct dentry *dentry, const char *symname)
    130{
    131	struct inode *inode;
    132	int error = -ENOSPC;
    133
    134	inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0);
    135	if (inode) {
    136		int l = strlen(symname)+1;
    137		error = page_symlink(inode, symname, l);
    138		if (!error) {
    139			d_instantiate(dentry, inode);
    140			dget(dentry);
    141			dir->i_mtime = dir->i_ctime = current_time(dir);
    142		} else
    143			iput(inode);
    144	}
    145	return error;
    146}
    147
    148static int ramfs_tmpfile(struct user_namespace *mnt_userns,
    149			 struct inode *dir, struct dentry *dentry, umode_t mode)
    150{
    151	struct inode *inode;
    152
    153	inode = ramfs_get_inode(dir->i_sb, dir, mode, 0);
    154	if (!inode)
    155		return -ENOSPC;
    156	d_tmpfile(dentry, inode);
    157	return 0;
    158}
    159
    160static const struct inode_operations ramfs_dir_inode_operations = {
    161	.create		= ramfs_create,
    162	.lookup		= simple_lookup,
    163	.link		= simple_link,
    164	.unlink		= simple_unlink,
    165	.symlink	= ramfs_symlink,
    166	.mkdir		= ramfs_mkdir,
    167	.rmdir		= simple_rmdir,
    168	.mknod		= ramfs_mknod,
    169	.rename		= simple_rename,
    170	.tmpfile	= ramfs_tmpfile,
    171};
    172
    173/*
    174 * Display the mount options in /proc/mounts.
    175 */
    176static int ramfs_show_options(struct seq_file *m, struct dentry *root)
    177{
    178	struct ramfs_fs_info *fsi = root->d_sb->s_fs_info;
    179
    180	if (fsi->mount_opts.mode != RAMFS_DEFAULT_MODE)
    181		seq_printf(m, ",mode=%o", fsi->mount_opts.mode);
    182	return 0;
    183}
    184
    185static const struct super_operations ramfs_ops = {
    186	.statfs		= simple_statfs,
    187	.drop_inode	= generic_delete_inode,
    188	.show_options	= ramfs_show_options,
    189};
    190
    191enum ramfs_param {
    192	Opt_mode,
    193};
    194
    195const struct fs_parameter_spec ramfs_fs_parameters[] = {
    196	fsparam_u32oct("mode",	Opt_mode),
    197	{}
    198};
    199
    200static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
    201{
    202	struct fs_parse_result result;
    203	struct ramfs_fs_info *fsi = fc->s_fs_info;
    204	int opt;
    205
    206	opt = fs_parse(fc, ramfs_fs_parameters, param, &result);
    207	if (opt == -ENOPARAM) {
    208		opt = vfs_parse_fs_param_source(fc, param);
    209		if (opt != -ENOPARAM)
    210			return opt;
    211		/*
    212		 * We might like to report bad mount options here;
    213		 * but traditionally ramfs has ignored all mount options,
    214		 * and as it is used as a !CONFIG_SHMEM simple substitute
    215		 * for tmpfs, better continue to ignore other mount options.
    216		 */
    217		return 0;
    218	}
    219	if (opt < 0)
    220		return opt;
    221
    222	switch (opt) {
    223	case Opt_mode:
    224		fsi->mount_opts.mode = result.uint_32 & S_IALLUGO;
    225		break;
    226	}
    227
    228	return 0;
    229}
    230
    231static int ramfs_fill_super(struct super_block *sb, struct fs_context *fc)
    232{
    233	struct ramfs_fs_info *fsi = sb->s_fs_info;
    234	struct inode *inode;
    235
    236	sb->s_maxbytes		= MAX_LFS_FILESIZE;
    237	sb->s_blocksize		= PAGE_SIZE;
    238	sb->s_blocksize_bits	= PAGE_SHIFT;
    239	sb->s_magic		= RAMFS_MAGIC;
    240	sb->s_op		= &ramfs_ops;
    241	sb->s_time_gran		= 1;
    242
    243	inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
    244	sb->s_root = d_make_root(inode);
    245	if (!sb->s_root)
    246		return -ENOMEM;
    247
    248	return 0;
    249}
    250
    251static int ramfs_get_tree(struct fs_context *fc)
    252{
    253	return get_tree_nodev(fc, ramfs_fill_super);
    254}
    255
    256static void ramfs_free_fc(struct fs_context *fc)
    257{
    258	kfree(fc->s_fs_info);
    259}
    260
    261static const struct fs_context_operations ramfs_context_ops = {
    262	.free		= ramfs_free_fc,
    263	.parse_param	= ramfs_parse_param,
    264	.get_tree	= ramfs_get_tree,
    265};
    266
    267int ramfs_init_fs_context(struct fs_context *fc)
    268{
    269	struct ramfs_fs_info *fsi;
    270
    271	fsi = kzalloc(sizeof(*fsi), GFP_KERNEL);
    272	if (!fsi)
    273		return -ENOMEM;
    274
    275	fsi->mount_opts.mode = RAMFS_DEFAULT_MODE;
    276	fc->s_fs_info = fsi;
    277	fc->ops = &ramfs_context_ops;
    278	return 0;
    279}
    280
    281static void ramfs_kill_sb(struct super_block *sb)
    282{
    283	kfree(sb->s_fs_info);
    284	kill_litter_super(sb);
    285}
    286
    287static struct file_system_type ramfs_fs_type = {
    288	.name		= "ramfs",
    289	.init_fs_context = ramfs_init_fs_context,
    290	.parameters	= ramfs_fs_parameters,
    291	.kill_sb	= ramfs_kill_sb,
    292	.fs_flags	= FS_USERNS_MOUNT,
    293};
    294
    295static int __init init_ramfs_fs(void)
    296{
    297	return register_filesystem(&ramfs_fs_type);
    298}
    299fs_initcall(init_ramfs_fs);