aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2009-03-31 18:24:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:22 -0400
commitc3b1b1cbf002e65a3cabd479e68b5f35886a26db (patch)
tree20286cf60de629dc00eaff4cd712347f9d9a2278
parentbb233fdfc7b7cefe45bfa2e8d1b24e79c60a48e5 (diff)
ramfs: add support for "mode=" mount option
Addresses http://bugzilla.kernel.org/show_bug.cgi?id=12843 "I use ramfs instead of tmpfs for /tmp because I don't use swap on my laptop. Some apps need 1777 mode for /tmp directory, but ramfs does not support 'mode=' mount option." Reported-by: Avan Anishchuk <matimatik@gmail.com> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ramfs/inode.c94
1 files changed, 86 insertions, 8 deletions
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
42static const struct super_operations ramfs_ops; 45static const struct super_operations ramfs_ops;
43static const struct inode_operations ramfs_dir_inode_operations; 46static const struct inode_operations ramfs_dir_inode_operations;
44 47
@@ -158,12 +161,75 @@ static const struct inode_operations ramfs_dir_inode_operations = {
158static const struct super_operations ramfs_ops = { 161static 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
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;
161}; 183};
162 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 default:
206 printk(KERN_ERR "ramfs: bad mount option: %s\n", p);
207 return -EINVAL;
208 }
209 }
210
211 return 0;
212}
213
163static int ramfs_fill_super(struct super_block * sb, void * data, int silent) 214static 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;
253fail:
254 kfree(fsi);
255 iput(inode);
256 return err;
185} 257}
186 258
187int ramfs_get_sb(struct file_system_type *fs_type, 259int 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
272static void ramfs_kill_sb(struct super_block *sb)
273{
274 kfree(sb->s_fs_info);
275 kill_litter_super(sb);
276}
277
200static struct file_system_type ramfs_fs_type = { 278static 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};
205static struct file_system_type rootfs_fs_type = { 283static struct file_system_type rootfs_fs_type = {
206 .name = "rootfs", 284 .name = "rootfs",