diff options
Diffstat (limited to 'fs/affs/super.c')
-rw-r--r-- | fs/affs/super.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/fs/affs/super.c b/fs/affs/super.c index 63f5183f263b..104fdcb3a7fc 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/parser.h> | 16 | #include <linux/parser.h> |
17 | #include <linux/magic.h> | 17 | #include <linux/magic.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/smp_lock.h> | ||
19 | #include "affs.h" | 20 | #include "affs.h" |
20 | 21 | ||
21 | extern struct timezone sys_tz; | 22 | extern struct timezone sys_tz; |
@@ -24,49 +25,67 @@ static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); | |||
24 | static int affs_remount (struct super_block *sb, int *flags, char *data); | 25 | static int affs_remount (struct super_block *sb, int *flags, char *data); |
25 | 26 | ||
26 | static void | 27 | static void |
28 | affs_commit_super(struct super_block *sb, int clean) | ||
29 | { | ||
30 | struct affs_sb_info *sbi = AFFS_SB(sb); | ||
31 | struct buffer_head *bh = sbi->s_root_bh; | ||
32 | struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh); | ||
33 | |||
34 | tail->bm_flag = cpu_to_be32(clean); | ||
35 | secs_to_datestamp(get_seconds(), &tail->disk_change); | ||
36 | affs_fix_checksum(sb, bh); | ||
37 | mark_buffer_dirty(bh); | ||
38 | } | ||
39 | |||
40 | static void | ||
27 | affs_put_super(struct super_block *sb) | 41 | affs_put_super(struct super_block *sb) |
28 | { | 42 | { |
29 | struct affs_sb_info *sbi = AFFS_SB(sb); | 43 | struct affs_sb_info *sbi = AFFS_SB(sb); |
30 | pr_debug("AFFS: put_super()\n"); | 44 | pr_debug("AFFS: put_super()\n"); |
31 | 45 | ||
32 | if (!(sb->s_flags & MS_RDONLY)) { | 46 | lock_kernel(); |
33 | AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1); | 47 | |
34 | secs_to_datestamp(get_seconds(), | 48 | if (!(sb->s_flags & MS_RDONLY)) |
35 | &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change); | 49 | affs_commit_super(sb, 1); |
36 | affs_fix_checksum(sb, sbi->s_root_bh); | ||
37 | mark_buffer_dirty(sbi->s_root_bh); | ||
38 | } | ||
39 | 50 | ||
40 | kfree(sbi->s_prefix); | 51 | kfree(sbi->s_prefix); |
41 | affs_free_bitmap(sb); | 52 | affs_free_bitmap(sb); |
42 | affs_brelse(sbi->s_root_bh); | 53 | affs_brelse(sbi->s_root_bh); |
43 | kfree(sbi); | 54 | kfree(sbi); |
44 | sb->s_fs_info = NULL; | 55 | sb->s_fs_info = NULL; |
45 | return; | 56 | |
57 | unlock_kernel(); | ||
46 | } | 58 | } |
47 | 59 | ||
48 | static void | 60 | static void |
49 | affs_write_super(struct super_block *sb) | 61 | affs_write_super(struct super_block *sb) |
50 | { | 62 | { |
51 | int clean = 2; | 63 | int clean = 2; |
52 | struct affs_sb_info *sbi = AFFS_SB(sb); | ||
53 | 64 | ||
65 | lock_super(sb); | ||
54 | if (!(sb->s_flags & MS_RDONLY)) { | 66 | if (!(sb->s_flags & MS_RDONLY)) { |
55 | // if (sbi->s_bitmap[i].bm_bh) { | 67 | // if (sbi->s_bitmap[i].bm_bh) { |
56 | // if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) { | 68 | // if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) { |
57 | // clean = 0; | 69 | // clean = 0; |
58 | AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(clean); | 70 | affs_commit_super(sb, clean); |
59 | secs_to_datestamp(get_seconds(), | ||
60 | &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change); | ||
61 | affs_fix_checksum(sb, sbi->s_root_bh); | ||
62 | mark_buffer_dirty(sbi->s_root_bh); | ||
63 | sb->s_dirt = !clean; /* redo until bitmap synced */ | 71 | sb->s_dirt = !clean; /* redo until bitmap synced */ |
64 | } else | 72 | } else |
65 | sb->s_dirt = 0; | 73 | sb->s_dirt = 0; |
74 | unlock_super(sb); | ||
66 | 75 | ||
67 | pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); | 76 | pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); |
68 | } | 77 | } |
69 | 78 | ||
79 | static int | ||
80 | affs_sync_fs(struct super_block *sb, int wait) | ||
81 | { | ||
82 | lock_super(sb); | ||
83 | affs_commit_super(sb, 2); | ||
84 | sb->s_dirt = 0; | ||
85 | unlock_super(sb); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
70 | static struct kmem_cache * affs_inode_cachep; | 89 | static struct kmem_cache * affs_inode_cachep; |
71 | 90 | ||
72 | static struct inode *affs_alloc_inode(struct super_block *sb) | 91 | static struct inode *affs_alloc_inode(struct super_block *sb) |
@@ -124,6 +143,7 @@ static const struct super_operations affs_sops = { | |||
124 | .clear_inode = affs_clear_inode, | 143 | .clear_inode = affs_clear_inode, |
125 | .put_super = affs_put_super, | 144 | .put_super = affs_put_super, |
126 | .write_super = affs_write_super, | 145 | .write_super = affs_write_super, |
146 | .sync_fs = affs_sync_fs, | ||
127 | .statfs = affs_statfs, | 147 | .statfs = affs_statfs, |
128 | .remount_fs = affs_remount, | 148 | .remount_fs = affs_remount, |
129 | .show_options = generic_show_options, | 149 | .show_options = generic_show_options, |
@@ -507,6 +527,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
507 | kfree(new_opts); | 527 | kfree(new_opts); |
508 | return -EINVAL; | 528 | return -EINVAL; |
509 | } | 529 | } |
530 | lock_kernel(); | ||
510 | replace_mount_options(sb, new_opts); | 531 | replace_mount_options(sb, new_opts); |
511 | 532 | ||
512 | sbi->s_flags = mount_flags; | 533 | sbi->s_flags = mount_flags; |
@@ -514,8 +535,10 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
514 | sbi->s_uid = uid; | 535 | sbi->s_uid = uid; |
515 | sbi->s_gid = gid; | 536 | sbi->s_gid = gid; |
516 | 537 | ||
517 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 538 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { |
539 | unlock_kernel(); | ||
518 | return 0; | 540 | return 0; |
541 | } | ||
519 | if (*flags & MS_RDONLY) { | 542 | if (*flags & MS_RDONLY) { |
520 | sb->s_dirt = 1; | 543 | sb->s_dirt = 1; |
521 | while (sb->s_dirt) | 544 | while (sb->s_dirt) |
@@ -524,6 +547,7 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
524 | } else | 547 | } else |
525 | res = affs_init_bitmap(sb, flags); | 548 | res = affs_init_bitmap(sb, flags); |
526 | 549 | ||
550 | unlock_kernel(); | ||
527 | return res; | 551 | return res; |
528 | } | 552 | } |
529 | 553 | ||