Blame view
fs/ramfs/inode.c
7.05 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* * Resizable simple ram filesystem for Linux. * * Copyright (C) 2000 Linus Torvalds. * 2000 Transmeta Corp. * * Usage limits added by David Gibson, Linuxcare Australia. * This file is released under the GPL. */ /* * NOTE! This filesystem is probably most useful * not as a real filesystem, but as an example of * how virtual filesystems can be written. * * It doesn't get much simpler than this. Consider * that this file implements the full semantics of * a POSIX-compliant read-write filesystem. * * Note in particular how the filesystem does not * need to implement any data structures of its own * to keep track of the virtual data: using the VFS * caches is sufficient. */ #include <linux/module.h> #include <linux/fs.h> #include <linux/pagemap.h> #include <linux/highmem.h> |
8dde0509e [PATCH] ramfs: up... |
30 |
#include <linux/time.h> |
1da177e4c Linux-2.6.12-rc2 |
31 32 |
#include <linux/init.h> #include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
33 34 |
#include <linux/backing-dev.h> #include <linux/ramfs.h> |
e8edc6e03 Detach sched.h fr... |
35 |
#include <linux/sched.h> |
c3b1b1cbf ramfs: add suppor... |
36 |
#include <linux/parser.h> |
a7e3108cc ramfs: move RAMFS... |
37 |
#include <linux/magic.h> |
5a0e3ad6a include cleanup: ... |
38 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
39 |
#include <asm/uaccess.h> |
642fb4d1f [PATCH] NOMMU: Pr... |
40 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
41 |
|
c3b1b1cbf ramfs: add suppor... |
42 |
#define RAMFS_DEFAULT_MODE 0755 |
ee9b6d61a [PATCH] Mark stru... |
43 |
static const struct super_operations ramfs_ops; |
c5ef1c42c [PATCH] mark stru... |
44 |
static const struct inode_operations ramfs_dir_inode_operations; |
1da177e4c Linux-2.6.12-rc2 |
45 46 |
static struct backing_dev_info ramfs_backing_dev_info = { |
d993831fa writeback: add na... |
47 |
.name = "ramfs", |
1da177e4c Linux-2.6.12-rc2 |
48 |
.ra_pages = 0, /* No readahead */ |
e4ad08fe6 mm: bdi: add sepa... |
49 |
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | |
1da177e4c Linux-2.6.12-rc2 |
50 51 52 |
BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, }; |
454abafe9 ramfs: replace in... |
53 54 |
struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, int mode, dev_t dev) |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 |
{ struct inode * inode = new_inode(sb); if (inode) { |
85fe4025c fs: do not assign... |
59 |
inode->i_ino = get_next_ino(); |
454abafe9 ramfs: replace in... |
60 |
inode_init_owner(inode, dir, mode); |
1da177e4c Linux-2.6.12-rc2 |
61 62 |
inode->i_mapping->a_ops = &ramfs_aops; inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; |
769848c03 Add __GFP_MOVABLE... |
63 |
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); |
ba9ddf493 Ramfs and Ram Dis... |
64 |
mapping_set_unevictable(inode->i_mapping); |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; switch (mode & S_IFMT) { default: init_special_inode(inode, mode, dev); break; case S_IFREG: inode->i_op = &ramfs_file_inode_operations; inode->i_fop = &ramfs_file_operations; break; case S_IFDIR: inode->i_op = &ramfs_dir_inode_operations; inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ |
d8c76e6f4 [PATCH] r/o bind ... |
79 |
inc_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; break; } } return inode; } /* * File creation. Allocate an inode, and we're done.. */ /* SMP-safe */ static int ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { |
454abafe9 ramfs: replace in... |
96 |
struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev); |
1da177e4c Linux-2.6.12-rc2 |
97 98 99 |
int error = -ENOSPC; if (inode) { |
1da177e4c Linux-2.6.12-rc2 |
100 101 102 |
d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ error = 0; |
8dde0509e [PATCH] ramfs: up... |
103 |
dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
1da177e4c Linux-2.6.12-rc2 |
104 105 106 107 108 109 110 111 |
} return error; } static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) { int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) |
d8c76e6f4 [PATCH] r/o bind ... |
112 |
inc_nlink(dir); |
1da177e4c Linux-2.6.12-rc2 |
113 114 115 116 117 118 119 120 121 122 123 124 |
return retval; } static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); } static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) { struct inode *inode; int error = -ENOSPC; |
454abafe9 ramfs: replace in... |
125 |
inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0); |
1da177e4c Linux-2.6.12-rc2 |
126 127 128 129 |
if (inode) { int l = strlen(symname)+1; error = page_symlink(inode, symname, l); if (!error) { |
1da177e4c Linux-2.6.12-rc2 |
130 131 |
d_instantiate(dentry, inode); dget(dentry); |
ecbd3a632 [PATCH] ramfs nee... |
132 |
dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
1da177e4c Linux-2.6.12-rc2 |
133 134 135 136 137 |
} else iput(inode); } return error; } |
c5ef1c42c [PATCH] mark stru... |
138 |
static const struct inode_operations ramfs_dir_inode_operations = { |
1da177e4c Linux-2.6.12-rc2 |
139 140 141 142 143 144 145 146 147 148 |
.create = ramfs_create, .lookup = simple_lookup, .link = simple_link, .unlink = simple_unlink, .symlink = ramfs_symlink, .mkdir = ramfs_mkdir, .rmdir = simple_rmdir, .mknod = ramfs_mknod, .rename = simple_rename, }; |
ee9b6d61a [PATCH] Mark stru... |
149 |
static const struct super_operations ramfs_ops = { |
1da177e4c Linux-2.6.12-rc2 |
150 151 |
.statfs = simple_statfs, .drop_inode = generic_delete_inode, |
c3b1b1cbf ramfs: add suppor... |
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
.show_options = generic_show_options, }; struct ramfs_mount_opts { umode_t mode; }; enum { Opt_mode, Opt_err }; static const match_table_t tokens = { {Opt_mode, "mode=%o"}, {Opt_err, NULL} }; struct ramfs_fs_info { struct ramfs_mount_opts mount_opts; |
1da177e4c Linux-2.6.12-rc2 |
171 |
}; |
c3b1b1cbf ramfs: add suppor... |
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) { substring_t args[MAX_OPT_ARGS]; int option; int token; char *p; opts->mode = RAMFS_DEFAULT_MODE; while ((p = strsep(&data, ",")) != NULL) { if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case Opt_mode: if (match_octal(&args[0], &option)) return -EINVAL; opts->mode = option & S_IALLUGO; break; |
0a8eba9b7 ramfs: ignore unk... |
192 193 194 195 196 197 |
/* * We might like to report bad mount options here; * but traditionally ramfs has ignored all mount options, * and as it is used as a !CONFIG_SHMEM simple substitute * for tmpfs, better continue to ignore other mount options. */ |
c3b1b1cbf ramfs: add suppor... |
198 199 200 201 202 |
} } return 0; } |
da5e4ef7f devtmpfs: support... |
203 |
int ramfs_fill_super(struct super_block *sb, void *data, int silent) |
1da177e4c Linux-2.6.12-rc2 |
204 |
{ |
c3b1b1cbf ramfs: add suppor... |
205 206 207 208 209 210 211 212 |
struct ramfs_fs_info *fsi; struct inode *inode = NULL; struct dentry *root; int err; save_mount_options(sb, data); fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); |
f8201abcb ramfs: fix double... |
213 |
sb->s_fs_info = fsi; |
c3b1b1cbf ramfs: add suppor... |
214 215 216 217 |
if (!fsi) { err = -ENOMEM; goto fail; } |
c3b1b1cbf ramfs: add suppor... |
218 219 220 221 |
err = ramfs_parse_options(data, &fsi->mount_opts); if (err) goto fail; |
1da177e4c Linux-2.6.12-rc2 |
222 |
|
f8201abcb ramfs: fix double... |
223 224 225 226 227 228 |
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = RAMFS_MAGIC; sb->s_op = &ramfs_ops; sb->s_time_gran = 1; |
454abafe9 ramfs: replace in... |
229 |
inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0); |
c3b1b1cbf ramfs: add suppor... |
230 231 232 233 |
if (!inode) { err = -ENOMEM; goto fail; } |
1da177e4c Linux-2.6.12-rc2 |
234 235 |
root = d_alloc_root(inode); |
f8201abcb ramfs: fix double... |
236 |
sb->s_root = root; |
1da177e4c Linux-2.6.12-rc2 |
237 |
if (!root) { |
c3b1b1cbf ramfs: add suppor... |
238 239 |
err = -ENOMEM; goto fail; |
1da177e4c Linux-2.6.12-rc2 |
240 |
} |
f8201abcb ramfs: fix double... |
241 |
|
1da177e4c Linux-2.6.12-rc2 |
242 |
return 0; |
c3b1b1cbf ramfs: add suppor... |
243 244 |
fail: kfree(fsi); |
f8201abcb ramfs: fix double... |
245 |
sb->s_fs_info = NULL; |
c3b1b1cbf ramfs: add suppor... |
246 247 |
iput(inode); return err; |
1da177e4c Linux-2.6.12-rc2 |
248 |
} |
3c26ff6e4 convert get_sb_no... |
249 250 |
struct dentry *ramfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c Linux-2.6.12-rc2 |
251 |
{ |
3c26ff6e4 convert get_sb_no... |
252 |
return mount_nodev(fs_type, flags, data, ramfs_fill_super); |
1da177e4c Linux-2.6.12-rc2 |
253 |
} |
3c26ff6e4 convert get_sb_no... |
254 255 |
static struct dentry *rootfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c Linux-2.6.12-rc2 |
256 |
{ |
3c26ff6e4 convert get_sb_no... |
257 |
return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super); |
1da177e4c Linux-2.6.12-rc2 |
258 |
} |
c3b1b1cbf ramfs: add suppor... |
259 260 261 262 263 |
static void ramfs_kill_sb(struct super_block *sb) { kfree(sb->s_fs_info); kill_litter_super(sb); } |
1da177e4c Linux-2.6.12-rc2 |
264 265 |
static struct file_system_type ramfs_fs_type = { .name = "ramfs", |
3c26ff6e4 convert get_sb_no... |
266 |
.mount = ramfs_mount, |
c3b1b1cbf ramfs: add suppor... |
267 |
.kill_sb = ramfs_kill_sb, |
1da177e4c Linux-2.6.12-rc2 |
268 269 270 |
}; static struct file_system_type rootfs_fs_type = { .name = "rootfs", |
3c26ff6e4 convert get_sb_no... |
271 |
.mount = rootfs_mount, |
1da177e4c Linux-2.6.12-rc2 |
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
.kill_sb = kill_litter_super, }; static int __init init_ramfs_fs(void) { return register_filesystem(&ramfs_fs_type); } static void __exit exit_ramfs_fs(void) { unregister_filesystem(&ramfs_fs_type); } module_init(init_ramfs_fs) module_exit(exit_ramfs_fs) int __init init_rootfs(void) { |
e0bf68dde mm: bdi init hooks |
290 291 292 293 294 295 296 297 298 299 300 |
int err; err = bdi_init(&ramfs_backing_dev_info); if (err) return err; err = register_filesystem(&rootfs_fs_type); if (err) bdi_destroy(&ramfs_backing_dev_info); return err; |
1da177e4c Linux-2.6.12-rc2 |
301 302 303 |
} MODULE_LICENSE("GPL"); |