diff options
Diffstat (limited to 'fs/ufs/super.c')
| -rw-r--r-- | fs/ufs/super.c | 65 | 
1 files changed, 53 insertions, 12 deletions
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,  |