diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/udf/balloc.c | 37 | ||||
| -rw-r--r-- | fs/udf/ialloc.c | 5 | ||||
| -rw-r--r-- | fs/udf/super.c | 44 | ||||
| -rw-r--r-- | fs/udf/udf_sb.h | 2 | ||||
| -rw-r--r-- | fs/udf/udfdecl.h | 11 | 
5 files changed, 52 insertions, 47 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 58be702cb42..e48e9a3af76 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -140,17 +140,17 @@ static inline int load_block_bitmap(struct super_block *sb,  	return slot;  } -static bool udf_add_free_space(struct udf_sb_info *sbi, -				u16 partition, u32 cnt) +static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)  { +	struct udf_sb_info *sbi = UDF_SB(sb);  	struct logicalVolIntegrityDesc *lvid; -	if (sbi->s_lvid_bh == NULL) -		return false; +	if (!sbi->s_lvid_bh) +		return;  	lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;  	le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); -	return true; +	udf_updated_lvid(sb);  }  static void udf_bitmap_free_blocks(struct super_block *sb, @@ -209,7 +209,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,  			} else {  				if (inode)  					vfs_dq_free_block(inode, 1); -				udf_add_free_space(sbi, sbi->s_partition, 1); +				udf_add_free_space(sb, sbi->s_partition, 1);  			}  		}  		mark_buffer_dirty(bh); @@ -220,9 +220,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,  	} while (overflow);  error_return: -	sb->s_dirt = 1; -	if (sbi->s_lvid_bh) -		mark_buffer_dirty(sbi->s_lvid_bh);  	mutex_unlock(&sbi->s_alloc_mutex);  } @@ -279,9 +276,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,  	} while (block_count > 0);  out: -	if (udf_add_free_space(sbi, partition, -alloc_count)) -		mark_buffer_dirty(sbi->s_lvid_bh); -	sb->s_dirt = 1; +	udf_add_free_space(sb, partition, -alloc_count);  	mutex_unlock(&sbi->s_alloc_mutex);  	return alloc_count;  } @@ -411,9 +406,7 @@ got_block:  	mark_buffer_dirty(bh); -	if (udf_add_free_space(sbi, partition, -1)) -		mark_buffer_dirty(sbi->s_lvid_bh); -	sb->s_dirt = 1; +	udf_add_free_space(sb, partition, -1);  	mutex_unlock(&sbi->s_alloc_mutex);  	*err = 0;  	return newblock; @@ -457,8 +450,7 @@ static void udf_table_free_blocks(struct super_block *sb,  	   could occure, but.. oh well */  	if (inode)  		vfs_dq_free_block(inode, count); -	if (udf_add_free_space(sbi, sbi->s_partition, count)) -		mark_buffer_dirty(sbi->s_lvid_bh); +	udf_add_free_space(sb, sbi->s_partition, count);  	start = bloc->logicalBlockNum + offset;  	end = bloc->logicalBlockNum + offset + count - 1; @@ -657,7 +649,6 @@ static void udf_table_free_blocks(struct super_block *sb,  	brelse(oepos.bh);  error_return: -	sb->s_dirt = 1;  	mutex_unlock(&sbi->s_alloc_mutex);  	return;  } @@ -722,10 +713,8 @@ static int udf_table_prealloc_blocks(struct super_block *sb,  	brelse(epos.bh); -	if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) { -		mark_buffer_dirty(sbi->s_lvid_bh); -		sb->s_dirt = 1; -	} +	if (alloc_count) +		udf_add_free_space(sb, partition, -alloc_count);  	mutex_unlock(&sbi->s_alloc_mutex);  	return alloc_count;  } @@ -823,10 +812,8 @@ static int udf_table_new_block(struct super_block *sb,  		udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);  	brelse(goal_epos.bh); -	if (udf_add_free_space(sbi, partition, -1)) -		mark_buffer_dirty(sbi->s_lvid_bh); +	udf_add_free_space(sb, partition, -1); -	sb->s_dirt = 1;  	mutex_unlock(&sbi->s_alloc_mutex);  	*err = 0;  	return newblock; diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 6eb279d5f4f..c10fa39f97e 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -49,8 +49,7 @@ void udf_free_inode(struct inode *inode)  			le32_add_cpu(&lvidiu->numDirs, -1);  		else  			le32_add_cpu(&lvidiu->numFiles, -1); - -		mark_buffer_dirty(sbi->s_lvid_bh); +		udf_updated_lvid(sb);  	}  	mutex_unlock(&sbi->s_alloc_mutex); @@ -122,7 +121,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)  		if (!(++uniqueID & 0x00000000FFFFFFFFUL))  			uniqueID += 16;  		lvhd->uniqueID = cpu_to_le64(uniqueID); -		mark_buffer_dirty(sbi->s_lvid_bh); +		udf_updated_lvid(sb);  	}  	mutex_unlock(&sbi->s_alloc_mutex);  	inode->i_mode = mode; diff --git a/fs/udf/super.c b/fs/udf/super.c index cae079eb5dd..72348cc855a 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -81,7 +81,7 @@ static char error_buf[1024];  /* These are the "meat" - everything else is stuffing */  static int udf_fill_super(struct super_block *, void *, int);  static void udf_put_super(struct super_block *); -static void udf_write_super(struct super_block *); +static int udf_sync_fs(struct super_block *, int);  static int udf_remount_fs(struct super_block *, int *, char *);  static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);  static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, @@ -178,7 +178,7 @@ static const struct super_operations udf_sb_ops = {  	.delete_inode	= udf_delete_inode,  	.clear_inode	= udf_clear_inode,  	.put_super	= udf_put_super, -	.write_super	= udf_write_super, +	.sync_fs	= udf_sync_fs,  	.statfs		= udf_statfs,  	.remount_fs	= udf_remount_fs,  	.show_options	= udf_show_options, @@ -553,17 +553,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt,  	return 1;  } -static void udf_write_super(struct super_block *sb) -{ -	lock_kernel(); - -	if (!(sb->s_flags & MS_RDONLY)) -		udf_open_lvid(sb); -	sb->s_dirt = 0; - -	unlock_kernel(); -} -  static int udf_remount_fs(struct super_block *sb, int *flags, char *options)  {  	struct udf_options uopt; @@ -1753,9 +1742,9 @@ static void udf_open_lvid(struct super_block *sb)  	struct buffer_head *bh = sbi->s_lvid_bh;  	struct logicalVolIntegrityDesc *lvid;  	struct logicalVolIntegrityDescImpUse *lvidiu; +  	if (!bh)  		return; -  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;  	lvidiu = udf_sb_lvidiu(sbi); @@ -1763,7 +1752,7 @@ static void udf_open_lvid(struct super_block *sb)  	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;  	udf_time_to_disk_stamp(&lvid->recordingDateAndTime,  				CURRENT_TIME); -	lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; +	lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);  	lvid->descTag.descCRC = cpu_to_le16(  		crc_itu_t(0, (char *)lvid + sizeof(struct tag), @@ -1771,6 +1760,7 @@ static void udf_open_lvid(struct super_block *sb)  	lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);  	mark_buffer_dirty(bh); +	sbi->s_lvid_dirty = 0;  }  static void udf_close_lvid(struct super_block *sb) @@ -1784,10 +1774,6 @@ static void udf_close_lvid(struct super_block *sb)  		return;  	lvid = (struct logicalVolIntegrityDesc *)bh->b_data; - -	if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN) -		return; -  	lvidiu = udf_sb_lvidiu(sbi);  	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;  	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; @@ -1806,6 +1792,7 @@ static void udf_close_lvid(struct super_block *sb)  	lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);  	mark_buffer_dirty(bh); +	sbi->s_lvid_dirty = 0;  }  static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) @@ -2092,6 +2079,25 @@ static void udf_put_super(struct super_block *sb)  	sb->s_fs_info = NULL;  } +static int udf_sync_fs(struct super_block *sb, int wait) +{ +	struct udf_sb_info *sbi = UDF_SB(sb); + +	mutex_lock(&sbi->s_alloc_mutex); +	if (sbi->s_lvid_dirty) { +		/* +		 * Blockdevice will be synced later so we don't have to submit +		 * the buffer for IO +		 */ +		mark_buffer_dirty(sbi->s_lvid_bh); +		sb->s_dirt = 0; +		sbi->s_lvid_dirty = 0; +	} +	mutex_unlock(&sbi->s_alloc_mutex); + +	return 0; +} +  static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)  {  	struct super_block *sb = dentry->d_sb; diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 46fea3ea70a..d113b72c276 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -148,6 +148,8 @@ struct udf_sb_info {  	struct inode		*s_vat_inode;  	struct mutex		s_alloc_mutex; +	/* Protected by s_alloc_mutex */ +	unsigned int		s_lvid_dirty;  };  static inline struct udf_sb_info *UDF_SB(struct super_block *sb) diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 9a2a9b61413..cac51b77a5d 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -111,6 +111,17 @@ struct extent_position {  /* super.c */  extern void udf_warning(struct super_block *, const char *, const char *, ...); +static inline void udf_updated_lvid(struct super_block *sb) +{ +	struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh; + +	BUG_ON(!bh); +	WARN_ON_ONCE(((struct logicalVolIntegrityDesc *) +		     bh->b_data)->integrityType != +		     cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN)); +	sb->s_dirt = 1; +	UDF_SB(sb)->s_lvid_dirty = 1; +}  /* namei.c */  extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,  | 
