summaryrefslogtreecommitdiffstats
path: root/fs/affs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/affs/super.c')
-rw-r--r--fs/affs/super.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 63f5183f263..104fdcb3a7f 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -16,6 +16,7 @@
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "affs.h"
extern struct timezone sys_tz;
@@ -24,49 +25,67 @@ static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
static int affs_remount (struct super_block *sb, int *flags, char *data);
static void
+affs_commit_super(struct super_block *sb, int clean)
+{
+ struct affs_sb_info *sbi = AFFS_SB(sb);
+ struct buffer_head *bh = sbi->s_root_bh;
+ struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh);
+
+ tail->bm_flag = cpu_to_be32(clean);
+ secs_to_datestamp(get_seconds(), &tail->disk_change);
+ affs_fix_checksum(sb, bh);
+ mark_buffer_dirty(bh);
+}
+
+static void
affs_put_super(struct super_block *sb)
{
struct affs_sb_info *sbi = AFFS_SB(sb);
pr_debug("AFFS: put_super()\n");
- if (!(sb->s_flags & MS_RDONLY)) {
- AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(1);
- secs_to_datestamp(get_seconds(),
- &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
- affs_fix_checksum(sb, sbi->s_root_bh);
- mark_buffer_dirty(sbi->s_root_bh);
- }
+ lock_kernel();
+
+ if (!(sb->s_flags & MS_RDONLY))
+ affs_commit_super(sb, 1);
kfree(sbi->s_prefix);
affs_free_bitmap(sb);
affs_brelse(sbi->s_root_bh);
kfree(sbi);
sb->s_fs_info = NULL;
- return;
+
+ unlock_kernel();
}
static void
affs_write_super(struct super_block *sb)
{
int clean = 2;
- struct affs_sb_info *sbi = AFFS_SB(sb);
+ lock_super(sb);
if (!(sb->s_flags & MS_RDONLY)) {
// if (sbi->s_bitmap[i].bm_bh) {
// if (buffer_dirty(sbi->s_bitmap[i].bm_bh)) {
// clean = 0;
- AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag = cpu_to_be32(clean);
- secs_to_datestamp(get_seconds(),
- &AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->disk_change);
- affs_fix_checksum(sb, sbi->s_root_bh);
- mark_buffer_dirty(sbi->s_root_bh);
+ affs_commit_super(sb, clean);
sb->s_dirt = !clean; /* redo until bitmap synced */
} else
sb->s_dirt = 0;
+ unlock_super(sb);
pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean);
}
+static int
+affs_sync_fs(struct super_block *sb, int wait)
+{
+ lock_super(sb);
+ affs_commit_super(sb, 2);
+ sb->s_dirt = 0;
+ unlock_super(sb);
+ return 0;
+}
+
static struct kmem_cache * affs_inode_cachep;
static struct inode *affs_alloc_inode(struct super_block *sb)
@@ -124,6 +143,7 @@ static const struct super_operations affs_sops = {
.clear_inode = affs_clear_inode,
.put_super = affs_put_super,
.write_super = affs_write_super,
+ .sync_fs = affs_sync_fs,
.statfs = affs_statfs,
.remount_fs = affs_remount,
.show_options = generic_show_options,
@@ -507,6 +527,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
kfree(new_opts);
return -EINVAL;
}
+ lock_kernel();
replace_mount_options(sb, new_opts);
sbi->s_flags = mount_flags;
@@ -514,8 +535,10 @@ affs_remount(struct super_block *sb, int *flags, char *data)
sbi->s_uid = uid;
sbi->s_gid = gid;
- if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+ if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
+ unlock_kernel();
return 0;
+ }
if (*flags & MS_RDONLY) {
sb->s_dirt = 1;
while (sb->s_dirt)
@@ -524,6 +547,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
} else
res = affs_init_bitmap(sb, flags);
+ unlock_kernel();
return res;
}