aboutsummaryrefslogtreecommitdiff
path: root/fs/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ufs')
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/ufs/file.c23
-rw-r--r--fs/ufs/super.c65
-rw-r--r--fs/ufs/ufs.h1
4 files changed, 55 insertions, 36 deletions
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 6321b797061..6f671f1ac27 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -666,6 +666,6 @@ not_empty:
const struct file_operations ufs_dir_operations = {
.read = generic_read_dir,
.readdir = ufs_readdir,
- .fsync = ufs_sync_file,
+ .fsync = simple_fsync,
.llseek = generic_file_llseek,
};
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 2bd3a161571..73655c61240 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -24,31 +24,10 @@
*/
#include <linux/fs.h>
-#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
#include "ufs_fs.h"
#include "ufs.h"
-
-int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
-{
- struct inode *inode = dentry->d_inode;
- int err;
- int ret;
-
- ret = sync_mapping_buffers(inode->i_mapping);
- if (!(inode->i_state & I_DIRTY))
- return ret;
- if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
- return ret;
-
- err = ufs_sync_inode(inode);
- if (ret == 0)
- ret = err;
- return ret;
-}
-
-
/*
* We have mostly NULL's here: the current defaults are ok for
* the ufs filesystem.
@@ -62,6 +41,6 @@ const struct file_operations ufs_file_operations = {
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.open = generic_file_open,
- .fsync = ufs_sync_file,
+ .fsync = simple_fsync,
.splice_read = generic_file_splice_read,
};
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 60359291761..5faed7954d0 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -263,6 +263,7 @@ void ufs_panic (struct super_block * sb, const char * function,
struct ufs_super_block_first * usb1;
va_list args;
+ lock_kernel();
uspi = UFS_SB(sb)->s_uspi;
usb1 = ubh_get_usb_first(uspi);
@@ -594,6 +595,9 @@ static void ufs_put_super_internal(struct super_block *sb)
UFSD("ENTER\n");
+
+ lock_kernel();
+
ufs_put_cstotal(sb);
size = uspi->s_cssize;
blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -621,6 +625,9 @@ static void ufs_put_super_internal(struct super_block *sb)
brelse (sbi->s_ucg[i]);
kfree (sbi->s_ucg);
kfree (base);
+
+ unlock_kernel();
+
UFSD("EXIT\n");
}
@@ -1118,32 +1125,45 @@ failed_nomem:
return -ENOMEM;
}
-static void ufs_write_super(struct super_block *sb)
+static int ufs_sync_fs(struct super_block *sb, int wait)
{
struct ufs_sb_private_info * uspi;
struct ufs_super_block_first * usb1;
struct ufs_super_block_third * usb3;
unsigned flags;
+ lock_super(sb);
lock_kernel();
+
UFSD("ENTER\n");
+
flags = UFS_SB(sb)->s_flags;
uspi = UFS_SB(sb)->s_uspi;
usb1 = ubh_get_usb_first(uspi);
usb3 = ubh_get_usb_third(uspi);
- if (!(sb->s_flags & MS_RDONLY)) {
- usb1->fs_time = cpu_to_fs32(sb, get_seconds());
- if ((flags & UFS_ST_MASK) == UFS_ST_SUN
- || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
- || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
- ufs_set_fs_state(sb, usb1, usb3,
- UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
- ufs_put_cstotal(sb);
- }
+ usb1->fs_time = cpu_to_fs32(sb, get_seconds());
+ if ((flags & UFS_ST_MASK) == UFS_ST_SUN ||
+ (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
+ (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
+ ufs_set_fs_state(sb, usb1, usb3,
+ UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
+ ufs_put_cstotal(sb);
sb->s_dirt = 0;
+
UFSD("EXIT\n");
unlock_kernel();
+ unlock_super(sb);
+
+ return 0;
+}
+
+static void ufs_write_super(struct super_block *sb)
+{
+ if (!(sb->s_flags & MS_RDONLY))
+ ufs_sync_fs(sb, 1);
+ else
+ sb->s_dirt = 0;
}
static void ufs_put_super(struct super_block *sb)
@@ -1152,6 +1172,9 @@ static void ufs_put_super(struct super_block *sb)
UFSD("ENTER\n");
+ if (sb->s_dirt)
+ ufs_write_super(sb);
+
if (!(sb->s_flags & MS_RDONLY))
ufs_put_super_internal(sb);
@@ -1171,7 +1194,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
struct ufs_super_block_third * usb3;
unsigned new_mount_opt, ufstype;
unsigned flags;
-
+
+ lock_kernel();
+ lock_super(sb);
uspi = UFS_SB(sb)->s_uspi;
flags = UFS_SB(sb)->s_flags;
usb1 = ubh_get_usb_first(uspi);
@@ -1184,17 +1209,24 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
ufstype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;
new_mount_opt = 0;
ufs_set_opt (new_mount_opt, ONERROR_LOCK);
- if (!ufs_parse_options (data, &new_mount_opt))
+ if (!ufs_parse_options (data, &new_mount_opt)) {
+ unlock_super(sb);
+ unlock_kernel();
return -EINVAL;
+ }
if (!(new_mount_opt & UFS_MOUNT_UFSTYPE)) {
new_mount_opt |= ufstype;
} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
printk("ufstype can't be changed during remount\n");
+ unlock_super(sb);
+ unlock_kernel();
return -EINVAL;
}
if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
UFS_SB(sb)->s_mount_opt = new_mount_opt;
+ unlock_super(sb);
+ unlock_kernel();
return 0;
}
@@ -1219,6 +1251,8 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
#ifndef CONFIG_UFS_FS_WRITE
printk("ufs was compiled with read-only support, "
"can't be mounted as read-write\n");
+ unlock_super(sb);
+ unlock_kernel();
return -EINVAL;
#else
if (ufstype != UFS_MOUNT_UFSTYPE_SUN &&
@@ -1227,16 +1261,22 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
printk("this ufstype is read-only supported\n");
+ unlock_super(sb);
+ unlock_kernel();
return -EINVAL;
}
if (!ufs_read_cylinder_structures(sb)) {
printk("failed during remounting\n");
+ unlock_super(sb);
+ unlock_kernel();
return -EPERM;
}
sb->s_flags &= ~MS_RDONLY;
#endif
}
UFS_SB(sb)->s_mount_opt = new_mount_opt;
+ unlock_super(sb);
+ unlock_kernel();
return 0;
}
@@ -1352,6 +1392,7 @@ static const struct super_operations ufs_super_ops = {
.delete_inode = ufs_delete_inode,
.put_super = ufs_put_super,
.write_super = ufs_write_super,
+ .sync_fs = ufs_sync_fs,
.statfs = ufs_statfs,
.remount_fs = ufs_remount,
.show_options = ufs_show_options,
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index d0c4acd4f1f..644e77e1359 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -99,7 +99,6 @@ extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
extern const struct inode_operations ufs_file_inode_operations;
extern const struct file_operations ufs_file_operations;
extern const struct address_space_operations ufs_aops;
-extern int ufs_sync_file(struct file *, struct dentry *, int);
/* ialloc.c */
extern void ufs_free_inode (struct inode *inode);