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