diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
commit | 9efe21cb82b5dbe3b0b2ae4de4eccc64ecb94e95 (patch) | |
tree | 7ff8833745d2f268f897f6fa4a27263b4a572245 /fs/ramfs | |
parent | de18836e447c2dc30120c0919b8db8ddc0401cc4 (diff) | |
parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff) |
Merge branch 'linus' into irq/threaded
Conflicts:
include/linux/irq.h
kernel/irq/handle.c
Diffstat (limited to 'fs/ramfs')
-rw-r--r-- | fs/ramfs/file-nommu.c | 21 | ||||
-rw-r--r-- | fs/ramfs/inode.c | 94 |
2 files changed, 90 insertions, 25 deletions
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 5d7c7ececa64..ebb2c417912c 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/backing-dev.h> | 19 | #include <linux/backing-dev.h> |
20 | #include <linux/ramfs.h> | 20 | #include <linux/ramfs.h> |
21 | #include <linux/quotaops.h> | ||
22 | #include <linux/pagevec.h> | 21 | #include <linux/pagevec.h> |
23 | #include <linux/mman.h> | 22 | #include <linux/mman.h> |
24 | 23 | ||
@@ -60,7 +59,6 @@ const struct inode_operations ramfs_file_inode_operations = { | |||
60 | */ | 59 | */ |
61 | int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | 60 | int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) |
62 | { | 61 | { |
63 | struct pagevec lru_pvec; | ||
64 | unsigned long npages, xpages, loop, limit; | 62 | unsigned long npages, xpages, loop, limit; |
65 | struct page *pages; | 63 | struct page *pages; |
66 | unsigned order; | 64 | unsigned order; |
@@ -103,24 +101,20 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
103 | memset(data, 0, newsize); | 101 | memset(data, 0, newsize); |
104 | 102 | ||
105 | /* attach all the pages to the inode's address space */ | 103 | /* attach all the pages to the inode's address space */ |
106 | pagevec_init(&lru_pvec, 0); | ||
107 | for (loop = 0; loop < npages; loop++) { | 104 | for (loop = 0; loop < npages; loop++) { |
108 | struct page *page = pages + loop; | 105 | struct page *page = pages + loop; |
109 | 106 | ||
110 | ret = add_to_page_cache(page, inode->i_mapping, loop, GFP_KERNEL); | 107 | ret = add_to_page_cache_lru(page, inode->i_mapping, loop, |
108 | GFP_KERNEL); | ||
111 | if (ret < 0) | 109 | if (ret < 0) |
112 | goto add_error; | 110 | goto add_error; |
113 | 111 | ||
114 | if (!pagevec_add(&lru_pvec, page)) | ||
115 | __pagevec_lru_add_file(&lru_pvec); | ||
116 | |||
117 | /* prevent the page from being discarded on memory pressure */ | 112 | /* prevent the page from being discarded on memory pressure */ |
118 | SetPageDirty(page); | 113 | SetPageDirty(page); |
119 | 114 | ||
120 | unlock_page(page); | 115 | unlock_page(page); |
121 | } | 116 | } |
122 | 117 | ||
123 | pagevec_lru_add_file(&lru_pvec); | ||
124 | return 0; | 118 | return 0; |
125 | 119 | ||
126 | fsize_exceeded: | 120 | fsize_exceeded: |
@@ -129,10 +123,8 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
129 | return -EFBIG; | 123 | return -EFBIG; |
130 | 124 | ||
131 | add_error: | 125 | add_error: |
132 | pagevec_lru_add_file(&lru_pvec); | 126 | while (loop < npages) |
133 | page_cache_release(pages + loop); | 127 | __free_page(pages + loop++); |
134 | for (loop++; loop < npages; loop++) | ||
135 | __free_page(pages + loop); | ||
136 | return ret; | 128 | return ret; |
137 | } | 129 | } |
138 | 130 | ||
@@ -205,11 +197,6 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) | |||
205 | if (ret) | 197 | if (ret) |
206 | return ret; | 198 | return ret; |
207 | 199 | ||
208 | /* by providing our own setattr() method, we skip this quotaism */ | ||
209 | if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || | ||
210 | (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid)) | ||
211 | ret = DQUOT_TRANSFER(inode, ia) ? -EDQUOT : 0; | ||
212 | |||
213 | /* pick out size-changing events */ | 200 | /* pick out size-changing events */ |
214 | if (ia->ia_valid & ATTR_SIZE) { | 201 | if (ia->ia_valid & ATTR_SIZE) { |
215 | loff_t size = i_size_read(inode); | 202 | loff_t size = i_size_read(inode); |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index b7e6ac706b87..a404fb88e456 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -33,12 +33,15 @@ | |||
33 | #include <linux/backing-dev.h> | 33 | #include <linux/backing-dev.h> |
34 | #include <linux/ramfs.h> | 34 | #include <linux/ramfs.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/parser.h> | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | #include "internal.h" | 38 | #include "internal.h" |
38 | 39 | ||
39 | /* some random number */ | 40 | /* some random number */ |
40 | #define RAMFS_MAGIC 0x858458f6 | 41 | #define RAMFS_MAGIC 0x858458f6 |
41 | 42 | ||
43 | #define RAMFS_DEFAULT_MODE 0755 | ||
44 | |||
42 | static const struct super_operations ramfs_ops; | 45 | static const struct super_operations ramfs_ops; |
43 | static const struct inode_operations ramfs_dir_inode_operations; | 46 | static const struct inode_operations ramfs_dir_inode_operations; |
44 | 47 | ||
@@ -158,12 +161,75 @@ static const struct inode_operations ramfs_dir_inode_operations = { | |||
158 | static const struct super_operations ramfs_ops = { | 161 | static const struct super_operations ramfs_ops = { |
159 | .statfs = simple_statfs, | 162 | .statfs = simple_statfs, |
160 | .drop_inode = generic_delete_inode, | 163 | .drop_inode = generic_delete_inode, |
164 | .show_options = generic_show_options, | ||
165 | }; | ||
166 | |||
167 | struct ramfs_mount_opts { | ||
168 | umode_t mode; | ||
169 | }; | ||
170 | |||
171 | enum { | ||
172 | Opt_mode, | ||
173 | Opt_err | ||
174 | }; | ||
175 | |||
176 | static const match_table_t tokens = { | ||
177 | {Opt_mode, "mode=%o"}, | ||
178 | {Opt_err, NULL} | ||
179 | }; | ||
180 | |||
181 | struct ramfs_fs_info { | ||
182 | struct ramfs_mount_opts mount_opts; | ||
161 | }; | 183 | }; |
162 | 184 | ||
185 | static 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 | default: | ||
206 | printk(KERN_ERR "ramfs: bad mount option: %s\n", p); | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
163 | static int ramfs_fill_super(struct super_block * sb, void * data, int silent) | 214 | static int ramfs_fill_super(struct super_block * sb, void * data, int silent) |
164 | { | 215 | { |
165 | struct inode * inode; | 216 | struct ramfs_fs_info *fsi; |
166 | struct dentry * root; | 217 | struct inode *inode = NULL; |
218 | struct dentry *root; | ||
219 | int err; | ||
220 | |||
221 | save_mount_options(sb, data); | ||
222 | |||
223 | fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); | ||
224 | if (!fsi) { | ||
225 | err = -ENOMEM; | ||
226 | goto fail; | ||
227 | } | ||
228 | sb->s_fs_info = fsi; | ||
229 | |||
230 | err = ramfs_parse_options(data, &fsi->mount_opts); | ||
231 | if (err) | ||
232 | goto fail; | ||
167 | 233 | ||
168 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 234 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
169 | sb->s_blocksize = PAGE_CACHE_SIZE; | 235 | sb->s_blocksize = PAGE_CACHE_SIZE; |
@@ -171,17 +237,23 @@ static int ramfs_fill_super(struct super_block * sb, void * data, int silent) | |||
171 | sb->s_magic = RAMFS_MAGIC; | 237 | sb->s_magic = RAMFS_MAGIC; |
172 | sb->s_op = &ramfs_ops; | 238 | sb->s_op = &ramfs_ops; |
173 | sb->s_time_gran = 1; | 239 | sb->s_time_gran = 1; |
174 | inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0); | 240 | inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0); |
175 | if (!inode) | 241 | if (!inode) { |
176 | return -ENOMEM; | 242 | err = -ENOMEM; |
243 | goto fail; | ||
244 | } | ||
177 | 245 | ||
178 | root = d_alloc_root(inode); | 246 | root = d_alloc_root(inode); |
179 | if (!root) { | 247 | if (!root) { |
180 | iput(inode); | 248 | err = -ENOMEM; |
181 | return -ENOMEM; | 249 | goto fail; |
182 | } | 250 | } |
183 | sb->s_root = root; | 251 | sb->s_root = root; |
184 | return 0; | 252 | return 0; |
253 | fail: | ||
254 | kfree(fsi); | ||
255 | iput(inode); | ||
256 | return err; | ||
185 | } | 257 | } |
186 | 258 | ||
187 | int ramfs_get_sb(struct file_system_type *fs_type, | 259 | int ramfs_get_sb(struct file_system_type *fs_type, |
@@ -197,10 +269,16 @@ static int rootfs_get_sb(struct file_system_type *fs_type, | |||
197 | mnt); | 269 | mnt); |
198 | } | 270 | } |
199 | 271 | ||
272 | static void ramfs_kill_sb(struct super_block *sb) | ||
273 | { | ||
274 | kfree(sb->s_fs_info); | ||
275 | kill_litter_super(sb); | ||
276 | } | ||
277 | |||
200 | static struct file_system_type ramfs_fs_type = { | 278 | static struct file_system_type ramfs_fs_type = { |
201 | .name = "ramfs", | 279 | .name = "ramfs", |
202 | .get_sb = ramfs_get_sb, | 280 | .get_sb = ramfs_get_sb, |
203 | .kill_sb = kill_litter_super, | 281 | .kill_sb = ramfs_kill_sb, |
204 | }; | 282 | }; |
205 | static struct file_system_type rootfs_fs_type = { | 283 | static struct file_system_type rootfs_fs_type = { |
206 | .name = "rootfs", | 284 | .name = "rootfs", |