diff options
Diffstat (limited to 'fs/cramfs/inode.c')
-rw-r--r-- | fs/cramfs/inode.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index e501ac3a49ff..06610cf94d57 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -17,14 +17,30 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
20 | #include <linux/cramfs_fs.h> | ||
21 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
22 | #include <linux/cramfs_fs_sb.h> | ||
23 | #include <linux/vfs.h> | 21 | #include <linux/vfs.h> |
24 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
25 | 23 | #include <uapi/linux/cramfs_fs.h> | |
26 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
27 | 25 | ||
26 | #include "internal.h" | ||
27 | |||
28 | /* | ||
29 | * cramfs super-block data in memory | ||
30 | */ | ||
31 | struct cramfs_sb_info { | ||
32 | unsigned long magic; | ||
33 | unsigned long size; | ||
34 | unsigned long blocks; | ||
35 | unsigned long files; | ||
36 | unsigned long flags; | ||
37 | }; | ||
38 | |||
39 | static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb) | ||
40 | { | ||
41 | return sb->s_fs_info; | ||
42 | } | ||
43 | |||
28 | static const struct super_operations cramfs_ops; | 44 | static const struct super_operations cramfs_ops; |
29 | static const struct inode_operations cramfs_dir_inode_operations; | 45 | static const struct inode_operations cramfs_dir_inode_operations; |
30 | static const struct file_operations cramfs_directory_operations; | 46 | static const struct file_operations cramfs_directory_operations; |
@@ -219,10 +235,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i | |||
219 | return read_buffers[buffer] + offset; | 235 | return read_buffers[buffer] + offset; |
220 | } | 236 | } |
221 | 237 | ||
222 | static void cramfs_put_super(struct super_block *sb) | 238 | static void cramfs_kill_sb(struct super_block *sb) |
223 | { | 239 | { |
224 | kfree(sb->s_fs_info); | 240 | struct cramfs_sb_info *sbi = CRAMFS_SB(sb); |
225 | sb->s_fs_info = NULL; | 241 | kill_block_super(sb); |
242 | kfree(sbi); | ||
226 | } | 243 | } |
227 | 244 | ||
228 | static int cramfs_remount(struct super_block *sb, int *flags, char *data) | 245 | static int cramfs_remount(struct super_block *sb, int *flags, char *data) |
@@ -261,7 +278,7 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
261 | if (super.magic == CRAMFS_MAGIC_WEND) { | 278 | if (super.magic == CRAMFS_MAGIC_WEND) { |
262 | if (!silent) | 279 | if (!silent) |
263 | printk(KERN_ERR "cramfs: wrong endianness\n"); | 280 | printk(KERN_ERR "cramfs: wrong endianness\n"); |
264 | goto out; | 281 | return -EINVAL; |
265 | } | 282 | } |
266 | 283 | ||
267 | /* check at 512 byte offset */ | 284 | /* check at 512 byte offset */ |
@@ -273,20 +290,20 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
273 | printk(KERN_ERR "cramfs: wrong endianness\n"); | 290 | printk(KERN_ERR "cramfs: wrong endianness\n"); |
274 | else if (!silent) | 291 | else if (!silent) |
275 | printk(KERN_ERR "cramfs: wrong magic\n"); | 292 | printk(KERN_ERR "cramfs: wrong magic\n"); |
276 | goto out; | 293 | return -EINVAL; |
277 | } | 294 | } |
278 | } | 295 | } |
279 | 296 | ||
280 | /* get feature flags first */ | 297 | /* get feature flags first */ |
281 | if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { | 298 | if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { |
282 | printk(KERN_ERR "cramfs: unsupported filesystem features\n"); | 299 | printk(KERN_ERR "cramfs: unsupported filesystem features\n"); |
283 | goto out; | 300 | return -EINVAL; |
284 | } | 301 | } |
285 | 302 | ||
286 | /* Check that the root inode is in a sane state */ | 303 | /* Check that the root inode is in a sane state */ |
287 | if (!S_ISDIR(super.root.mode)) { | 304 | if (!S_ISDIR(super.root.mode)) { |
288 | printk(KERN_ERR "cramfs: root is not a directory\n"); | 305 | printk(KERN_ERR "cramfs: root is not a directory\n"); |
289 | goto out; | 306 | return -EINVAL; |
290 | } | 307 | } |
291 | /* correct strange, hard-coded permissions of mkcramfs */ | 308 | /* correct strange, hard-coded permissions of mkcramfs */ |
292 | super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); | 309 | super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); |
@@ -310,22 +327,18 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
310 | (root_offset != 512 + sizeof(struct cramfs_super)))) | 327 | (root_offset != 512 + sizeof(struct cramfs_super)))) |
311 | { | 328 | { |
312 | printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); | 329 | printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); |
313 | goto out; | 330 | return -EINVAL; |
314 | } | 331 | } |
315 | 332 | ||
316 | /* Set it all up.. */ | 333 | /* Set it all up.. */ |
317 | sb->s_op = &cramfs_ops; | 334 | sb->s_op = &cramfs_ops; |
318 | root = get_cramfs_inode(sb, &super.root, 0); | 335 | root = get_cramfs_inode(sb, &super.root, 0); |
319 | if (IS_ERR(root)) | 336 | if (IS_ERR(root)) |
320 | goto out; | 337 | return PTR_ERR(root); |
321 | sb->s_root = d_make_root(root); | 338 | sb->s_root = d_make_root(root); |
322 | if (!sb->s_root) | 339 | if (!sb->s_root) |
323 | goto out; | 340 | return -ENOMEM; |
324 | return 0; | 341 | return 0; |
325 | out: | ||
326 | kfree(sbi); | ||
327 | sb->s_fs_info = NULL; | ||
328 | return -EINVAL; | ||
329 | } | 342 | } |
330 | 343 | ||
331 | static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 344 | static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
@@ -550,7 +563,6 @@ static const struct inode_operations cramfs_dir_inode_operations = { | |||
550 | }; | 563 | }; |
551 | 564 | ||
552 | static const struct super_operations cramfs_ops = { | 565 | static const struct super_operations cramfs_ops = { |
553 | .put_super = cramfs_put_super, | ||
554 | .remount_fs = cramfs_remount, | 566 | .remount_fs = cramfs_remount, |
555 | .statfs = cramfs_statfs, | 567 | .statfs = cramfs_statfs, |
556 | }; | 568 | }; |
@@ -565,7 +577,7 @@ static struct file_system_type cramfs_fs_type = { | |||
565 | .owner = THIS_MODULE, | 577 | .owner = THIS_MODULE, |
566 | .name = "cramfs", | 578 | .name = "cramfs", |
567 | .mount = cramfs_mount, | 579 | .mount = cramfs_mount, |
568 | .kill_sb = kill_block_super, | 580 | .kill_sb = cramfs_kill_sb, |
569 | .fs_flags = FS_REQUIRES_DEV, | 581 | .fs_flags = FS_REQUIRES_DEV, |
570 | }; | 582 | }; |
571 | MODULE_ALIAS_FS("cramfs"); | 583 | MODULE_ALIAS_FS("cramfs"); |