linux/fs/ramfs/inode.c
<<
>>
Prefs
   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 <asm/uaccess.h>
  39#include "internal.h"
  40
  41#define RAMFS_DEFAULT_MODE      0755
  42
  43static const struct super_operations ramfs_ops;
  44static const struct inode_operations ramfs_dir_inode_operations;
  45
  46static struct backing_dev_info ramfs_backing_dev_info = {
  47        .name           = "ramfs",
  48        .ra_pages       = 0,    /* No readahead */
  49        .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK |
  50                          BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
  51                          BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
  52};
  53
  54struct inode *ramfs_get_inode(struct super_block *sb,
  55                                const struct inode *dir, int mode, dev_t dev)
  56{
  57        struct inode * inode = new_inode(sb);
  58
  59        if (inode) {
  60                inode->i_ino = get_next_ino();
  61                inode_init_owner(inode, dir, mode);
  62                inode->i_mapping->a_ops = &ramfs_aops;
  63                inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
  64                mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
  65                mapping_set_unevictable(inode->i_mapping);
  66                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
  67                switch (mode & S_IFMT) {
  68                default:
  69                        init_special_inode(inode, mode, dev);
  70                        break;
  71                case S_IFREG:
  72                        inode->i_op = &ramfs_file_inode_operations;
  73                        inode->i_fop = &ramfs_file_operations;
  74                        break;
  75                case S_IFDIR:
  76                        inode->i_op = &ramfs_dir_inode_operations;
  77                        inode->i_fop = &simple_dir_operations;
  78
  79                        /* directory inodes start off with i_nlink == 2 (for "." entry) */
  80                        inc_nlink(inode);
  81                        break;
  82                case S_IFLNK:
  83                        inode->i_op = &page_symlink_inode_operations;
  84                        break;
  85                }
  86        }
  87        return inode;
  88}
  89
  90/*
  91 * File creation. Allocate an inode, and we're done..
  92 */
  93/* SMP-safe */
  94static int
  95ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  96{
  97        struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev);
  98        int error = -ENOSPC;
  99
 100        if (inode) {
 101                d_instantiate(dentry, inode);
 102                dget(dentry);   /* Extra count - pin the dentry in core */
 103                error = 0;
 104                dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 105        }
 106        return error;
 107}
 108
 109static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 110{
 111        int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);
 112        if (!retval)
 113                inc_nlink(dir);
 114        return retval;
 115}
 116
 117static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
 118{
 119        return ramfs_mknod(dir, dentry, mode | S_IFREG, 0);
 120}
 121
 122static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
 123{
 124        struct inode *inode;
 125        int error = -ENOSPC;
 126
 127        inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0);
 128        if (inode) {
 129                int l = strlen(symname)+1;
 130                error = page_symlink(inode, symname, l);
 131                if (!error) {
 132                        d_instantiate(dentry, inode);
 133                        dget(dentry);
 134                        dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 135                } else
 136                        iput(inode);
 137        }
 138        return error;
 139}
 140
 141static const struct inode_operations ramfs_dir_inode_operations = {
 142        .create         = ramfs_create,
 143        .lookup         = simple_lookup,
 144        .link           = simple_link,
 145        .unlink         = simple_unlink,
 146        .symlink        = ramfs_symlink,
 147        .mkdir          = ramfs_mkdir,
 148        .rmdir          = simple_rmdir,
 149        .mknod          = ramfs_mknod,
 150        .rename         = simple_rename,
 151};
 152
 153static const struct super_operations ramfs_ops = {
 154        .statfs         = simple_statfs,
 155        .drop_inode     = generic_delete_inode,
 156        .show_options   = generic_show_options,
 157};
 158
 159struct ramfs_mount_opts {
 160        umode_t mode;
 161};
 162
 163enum {
 164        Opt_mode,
 165        Opt_err
 166};
 167
 168static const match_table_t tokens = {
 169        {Opt_mode, "mode=%o"},
 170        {Opt_err, NULL}
 171};
 172
 173struct ramfs_fs_info {
 174        struct ramfs_mount_opts mount_opts;
 175};
 176
 177static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
 178{
 179        substring_t args[MAX_OPT_ARGS];
 180        int option;
 181        int token;
 182        char *p;
 183
 184        opts->mode = RAMFS_DEFAULT_MODE;
 185
 186        while ((p = strsep(&data, ",")) != NULL) {
 187                if (!*p)
 188                        continue;
 189
 190                token = match_token(p, tokens, args);
 191                switch (token) {
 192                case Opt_mode:
 193                        if (match_octal(&args[0], &option))
 194                                return -EINVAL;
 195                        opts->mode = option & S_IALLUGO;
 196                        break;
 197                /*
 198                 * We might like to report bad mount options here;
 199                 * but traditionally ramfs has ignored all mount options,
 200                 * and as it is used as a !CONFIG_SHMEM simple substitute
 201                 * for tmpfs, better continue to ignore other mount options.
 202                 */
 203                }
 204        }
 205
 206        return 0;
 207}
 208
 209int ramfs_fill_super(struct super_block *sb, void *data, int silent)
 210{
 211        struct ramfs_fs_info *fsi;
 212        struct inode *inode = NULL;
 213        struct dentry *root;
 214        int err;
 215
 216        save_mount_options(sb, data);
 217
 218        fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
 219        sb->s_fs_info = fsi;
 220        if (!fsi) {
 221                err = -ENOMEM;
 222                goto fail;
 223        }
 224
 225        err = ramfs_parse_options(data, &fsi->mount_opts);
 226        if (err)
 227                goto fail;
 228
 229        sb->s_maxbytes          = MAX_LFS_FILESIZE;
 230        sb->s_blocksize         = PAGE_CACHE_SIZE;
 231        sb->s_blocksize_bits    = PAGE_CACHE_SHIFT;
 232        sb->s_magic             = RAMFS_MAGIC;
 233        sb->s_op                = &ramfs_ops;
 234        sb->s_time_gran         = 1;
 235
 236        inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
 237        if (!inode) {
 238                err = -ENOMEM;
 239                goto fail;
 240        }
 241
 242        root = d_alloc_root(inode);
 243        sb->s_root = root;
 244        if (!root) {
 245                err = -ENOMEM;
 246                goto fail;
 247        }
 248
 249        return 0;
 250fail:
 251        kfree(fsi);
 252        sb->s_fs_info = NULL;
 253        iput(inode);
 254        return err;
 255}
 256
 257struct dentry *ramfs_mount(struct file_system_type *fs_type,
 258        int flags, const char *dev_name, void *data)
 259{
 260        return mount_nodev(fs_type, flags, data, ramfs_fill_super);
 261}
 262
 263static struct dentry *rootfs_mount(struct file_system_type *fs_type,
 264        int flags, const char *dev_name, void *data)
 265{
 266        return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
 267}
 268
 269static void ramfs_kill_sb(struct super_block *sb)
 270{
 271        kfree(sb->s_fs_info);
 272        kill_litter_super(sb);
 273}
 274
 275static struct file_system_type ramfs_fs_type = {
 276        .name           = "ramfs",
 277        .mount          = ramfs_mount,
 278        .kill_sb        = ramfs_kill_sb,
 279};
 280static struct file_system_type rootfs_fs_type = {
 281        .name           = "rootfs",
 282        .mount          = rootfs_mount,
 283        .kill_sb        = kill_litter_super,
 284};
 285
 286static int __init init_ramfs_fs(void)
 287{
 288        return register_filesystem(&ramfs_fs_type);
 289}
 290module_init(init_ramfs_fs)
 291
 292int __init init_rootfs(void)
 293{
 294        int err;
 295
 296        err = bdi_init(&ramfs_backing_dev_info);
 297        if (err)
 298                return err;
 299
 300        err = register_filesystem(&rootfs_fs_type);
 301        if (err)
 302                bdi_destroy(&ramfs_backing_dev_info);
 303
 304        return err;
 305}
 306
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.