diff options
| author | Wu Fengguang <fengguang.wu@intel.com> | 2009-03-31 18:24:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 11:59:22 -0400 |
| commit | c3b1b1cbf002e65a3cabd479e68b5f35886a26db (patch) | |
| tree | 20286cf60de629dc00eaff4cd712347f9d9a2278 /fs/ramfs | |
| parent | bb233fdfc7b7cefe45bfa2e8d1b24e79c60a48e5 (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>
Diffstat (limited to 'fs/ramfs')
| -rw-r--r-- | fs/ramfs/inode.c | 94 |
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 | |||
| 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", |
