Blame view
fs/ramfs/inode.c
6.91 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 |
/* * 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. */ |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 |
#include <linux/fs.h> #include <linux/pagemap.h> #include <linux/highmem.h> |
8dde0509e [PATCH] ramfs: up... |
28 |
#include <linux/time.h> |
1da177e4c Linux-2.6.12-rc2 |
29 30 |
#include <linux/init.h> #include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
31 32 |
#include <linux/backing-dev.h> #include <linux/ramfs.h> |
e8edc6e03 Detach sched.h fr... |
33 |
#include <linux/sched.h> |
c3b1b1cbf ramfs: add suppor... |
34 |
#include <linux/parser.h> |
a7e3108cc ramfs: move RAMFS... |
35 |
#include <linux/magic.h> |
5a0e3ad6a include cleanup: ... |
36 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
37 |
#include <asm/uaccess.h> |
642fb4d1f [PATCH] NOMMU: Pr... |
38 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
c3b1b1cbf ramfs: add suppor... |
40 |
#define RAMFS_DEFAULT_MODE 0755 |
ee9b6d61a [PATCH] Mark stru... |
41 |
static const struct super_operations ramfs_ops; |
c5ef1c42c [PATCH] mark stru... |
42 |
static const struct inode_operations ramfs_dir_inode_operations; |
1da177e4c Linux-2.6.12-rc2 |
43 44 |
static struct backing_dev_info ramfs_backing_dev_info = { |
d993831fa writeback: add na... |
45 |
.name = "ramfs", |
1da177e4c Linux-2.6.12-rc2 |
46 |
.ra_pages = 0, /* No readahead */ |
e4ad08fe6 mm: bdi: add sepa... |
47 |
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 |
BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, }; |
454abafe9 ramfs: replace in... |
51 |
struct inode *ramfs_get_inode(struct super_block *sb, |
632861f05 pohmelfs: propaga... |
52 |
const struct inode *dir, umode_t mode, dev_t dev) |
1da177e4c Linux-2.6.12-rc2 |
53 54 55 56 |
{ struct inode * inode = new_inode(sb); if (inode) { |
85fe4025c fs: do not assign... |
57 |
inode->i_ino = get_next_ino(); |
454abafe9 ramfs: replace in... |
58 |
inode_init_owner(inode, dir, mode); |
1da177e4c Linux-2.6.12-rc2 |
59 60 |
inode->i_mapping->a_ops = &ramfs_aops; inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; |
769848c03 Add __GFP_MOVABLE... |
61 |
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); |
ba9ddf493 Ramfs and Ram Dis... |
62 |
mapping_set_unevictable(inode->i_mapping); |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
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 ... |
77 |
inc_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
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 |
1a67aafb5 switch ->mknod() ... |
92 |
ramfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) |
1da177e4c Linux-2.6.12-rc2 |
93 |
{ |
454abafe9 ramfs: replace in... |
94 |
struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev); |
1da177e4c Linux-2.6.12-rc2 |
95 96 97 |
int error = -ENOSPC; if (inode) { |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 |
d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ error = 0; |
8dde0509e [PATCH] ramfs: up... |
101 |
dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
1da177e4c Linux-2.6.12-rc2 |
102 103 104 |
} return error; } |
18bb1db3e switch vfs_mkdir(... |
105 |
static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
106 107 108 |
{ int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) |
d8c76e6f4 [PATCH] r/o bind ... |
109 |
inc_nlink(dir); |
1da177e4c Linux-2.6.12-rc2 |
110 111 |
return retval; } |
4acdaf27e switch ->create()... |
112 |
static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) |
1da177e4c Linux-2.6.12-rc2 |
113 114 115 116 117 118 119 120 |
{ 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... |
121 |
inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0); |
1da177e4c Linux-2.6.12-rc2 |
122 123 124 125 |
if (inode) { int l = strlen(symname)+1; error = page_symlink(inode, symname, l); if (!error) { |
1da177e4c Linux-2.6.12-rc2 |
126 127 |
d_instantiate(dentry, inode); dget(dentry); |
ecbd3a632 [PATCH] ramfs nee... |
128 |
dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
1da177e4c Linux-2.6.12-rc2 |
129 130 131 132 133 |
} else iput(inode); } return error; } |
c5ef1c42c [PATCH] mark stru... |
134 |
static const struct inode_operations ramfs_dir_inode_operations = { |
1da177e4c Linux-2.6.12-rc2 |
135 136 137 138 139 140 141 142 143 144 |
.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... |
145 |
static const struct super_operations ramfs_ops = { |
1da177e4c Linux-2.6.12-rc2 |
146 147 |
.statfs = simple_statfs, .drop_inode = generic_delete_inode, |
c3b1b1cbf ramfs: add suppor... |
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
.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 |
167 |
}; |
c3b1b1cbf ramfs: add suppor... |
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
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... |
188 189 190 191 192 193 |
/* * 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... |
194 195 196 197 198 |
} } return 0; } |
da5e4ef7f devtmpfs: support... |
199 |
int ramfs_fill_super(struct super_block *sb, void *data, int silent) |
1da177e4c Linux-2.6.12-rc2 |
200 |
{ |
c3b1b1cbf ramfs: add suppor... |
201 202 203 204 205 206 207 208 |
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... |
209 |
sb->s_fs_info = fsi; |
c3b1b1cbf ramfs: add suppor... |
210 211 212 213 |
if (!fsi) { err = -ENOMEM; goto fail; } |
c3b1b1cbf ramfs: add suppor... |
214 215 216 217 |
err = ramfs_parse_options(data, &fsi->mount_opts); if (err) goto fail; |
1da177e4c Linux-2.6.12-rc2 |
218 |
|
f8201abcb ramfs: fix double... |
219 220 221 222 223 224 |
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... |
225 |
inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0); |
c3b1b1cbf ramfs: add suppor... |
226 227 228 229 |
if (!inode) { err = -ENOMEM; goto fail; } |
1da177e4c Linux-2.6.12-rc2 |
230 231 |
root = d_alloc_root(inode); |
f8201abcb ramfs: fix double... |
232 |
sb->s_root = root; |
1da177e4c Linux-2.6.12-rc2 |
233 |
if (!root) { |
c3b1b1cbf ramfs: add suppor... |
234 235 |
err = -ENOMEM; goto fail; |
1da177e4c Linux-2.6.12-rc2 |
236 |
} |
f8201abcb ramfs: fix double... |
237 |
|
1da177e4c Linux-2.6.12-rc2 |
238 |
return 0; |
c3b1b1cbf ramfs: add suppor... |
239 240 |
fail: kfree(fsi); |
f8201abcb ramfs: fix double... |
241 |
sb->s_fs_info = NULL; |
c3b1b1cbf ramfs: add suppor... |
242 243 |
iput(inode); return err; |
1da177e4c Linux-2.6.12-rc2 |
244 |
} |
3c26ff6e4 convert get_sb_no... |
245 246 |
struct dentry *ramfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c Linux-2.6.12-rc2 |
247 |
{ |
3c26ff6e4 convert get_sb_no... |
248 |
return mount_nodev(fs_type, flags, data, ramfs_fill_super); |
1da177e4c Linux-2.6.12-rc2 |
249 |
} |
3c26ff6e4 convert get_sb_no... |
250 251 |
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 |
252 |
{ |
3c26ff6e4 convert get_sb_no... |
253 |
return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super); |
1da177e4c Linux-2.6.12-rc2 |
254 |
} |
c3b1b1cbf ramfs: add suppor... |
255 256 257 258 259 |
static void ramfs_kill_sb(struct super_block *sb) { kfree(sb->s_fs_info); kill_litter_super(sb); } |
1da177e4c Linux-2.6.12-rc2 |
260 261 |
static struct file_system_type ramfs_fs_type = { .name = "ramfs", |
3c26ff6e4 convert get_sb_no... |
262 |
.mount = ramfs_mount, |
c3b1b1cbf ramfs: add suppor... |
263 |
.kill_sb = ramfs_kill_sb, |
1da177e4c Linux-2.6.12-rc2 |
264 265 266 |
}; static struct file_system_type rootfs_fs_type = { .name = "rootfs", |
3c26ff6e4 convert get_sb_no... |
267 |
.mount = rootfs_mount, |
1da177e4c Linux-2.6.12-rc2 |
268 269 270 271 272 273 274 |
.kill_sb = kill_litter_super, }; static int __init init_ramfs_fs(void) { return register_filesystem(&ramfs_fs_type); } |
1da177e4c Linux-2.6.12-rc2 |
275 |
module_init(init_ramfs_fs) |
1da177e4c Linux-2.6.12-rc2 |
276 277 278 |
int __init init_rootfs(void) { |
e0bf68dde mm: bdi init hooks |
279 280 281 282 283 284 285 286 287 288 289 |
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 |
290 |
} |