aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/balloc.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-03-16 13:27:37 -0400
committerJan Kara <jack@suse.cz>2009-04-02 07:36:28 -0400
commit146bca72c7e6ba52de82a63b1fce7934dc103dbc (patch)
treefee0aff001a5d5226518f0b67232f083f0931209 /fs/udf/balloc.c
parent40346005166329bc4b53e0c564aff3968c1ddaa0 (diff)
udf: Don't write integrity descriptor too often
We update information in logical volume integrity descriptor after each allocation (as LVID contains free space, number of directories and files on disk etc.). If the filesystem is on some phase change media, this leads to its quick degradation as such media is able to handle only 10000 overwrites or so. We solve the problem by writing new information into LVID only on umount, remount-ro and sync. This solves the problem at the price of longer media inconsistency (previously media became consistent after pdflush flushed dirty LVID buffer) but that should be acceptable. Report by and patch written in cooperation with Rich Coe <Richard.Coe@med.ge.com>. Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/balloc.c')
-rw-r--r--fs/udf/balloc.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 58be702cb42d..e48e9a3af763 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,
140 return slot; 140 return slot;
141} 141}
142 142
143static bool udf_add_free_space(struct udf_sb_info *sbi, 143static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
144 u16 partition, u32 cnt)
145{ 144{
145 struct udf_sb_info *sbi = UDF_SB(sb);
146 struct logicalVolIntegrityDesc *lvid; 146 struct logicalVolIntegrityDesc *lvid;
147 147
148 if (sbi->s_lvid_bh == NULL) 148 if (!sbi->s_lvid_bh)
149 return false; 149 return;
150 150
151 lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; 151 lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
152 le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); 152 le32_add_cpu(&lvid->freeSpaceTable[partition], cnt);
153 return true; 153 udf_updated_lvid(sb);
154} 154}
155 155
156static void udf_bitmap_free_blocks(struct super_block *sb, 156static void udf_bitmap_free_blocks(struct super_block *sb,
@@ -209,7 +209,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
209 } else { 209 } else {
210 if (inode) 210 if (inode)
211 vfs_dq_free_block(inode, 1); 211 vfs_dq_free_block(inode, 1);
212 udf_add_free_space(sbi, sbi->s_partition, 1); 212 udf_add_free_space(sb, sbi->s_partition, 1);
213 } 213 }
214 } 214 }
215 mark_buffer_dirty(bh); 215 mark_buffer_dirty(bh);
@@ -220,9 +220,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
220 } while (overflow); 220 } while (overflow);
221 221
222error_return: 222error_return:
223 sb->s_dirt = 1;
224 if (sbi->s_lvid_bh)
225 mark_buffer_dirty(sbi->s_lvid_bh);
226 mutex_unlock(&sbi->s_alloc_mutex); 223 mutex_unlock(&sbi->s_alloc_mutex);
227} 224}
228 225
@@ -279,9 +276,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
279 } while (block_count > 0); 276 } while (block_count > 0);
280 277
281out: 278out:
282 if (udf_add_free_space(sbi, partition, -alloc_count)) 279 udf_add_free_space(sb, partition, -alloc_count);
283 mark_buffer_dirty(sbi->s_lvid_bh);
284 sb->s_dirt = 1;
285 mutex_unlock(&sbi->s_alloc_mutex); 280 mutex_unlock(&sbi->s_alloc_mutex);
286 return alloc_count; 281 return alloc_count;
287} 282}
@@ -411,9 +406,7 @@ got_block:
411 406
412 mark_buffer_dirty(bh); 407 mark_buffer_dirty(bh);
413 408
414 if (udf_add_free_space(sbi, partition, -1)) 409 udf_add_free_space(sb, partition, -1);
415 mark_buffer_dirty(sbi->s_lvid_bh);
416 sb->s_dirt = 1;
417 mutex_unlock(&sbi->s_alloc_mutex); 410 mutex_unlock(&sbi->s_alloc_mutex);
418 *err = 0; 411 *err = 0;
419 return newblock; 412 return newblock;
@@ -457,8 +450,7 @@ static void udf_table_free_blocks(struct super_block *sb,
457 could occure, but.. oh well */ 450 could occure, but.. oh well */
458 if (inode) 451 if (inode)
459 vfs_dq_free_block(inode, count); 452 vfs_dq_free_block(inode, count);
460 if (udf_add_free_space(sbi, sbi->s_partition, count)) 453 udf_add_free_space(sb, sbi->s_partition, count);
461 mark_buffer_dirty(sbi->s_lvid_bh);
462 454
463 start = bloc->logicalBlockNum + offset; 455 start = bloc->logicalBlockNum + offset;
464 end = bloc->logicalBlockNum + offset + count - 1; 456 end = bloc->logicalBlockNum + offset + count - 1;
@@ -657,7 +649,6 @@ static void udf_table_free_blocks(struct super_block *sb,
657 brelse(oepos.bh); 649 brelse(oepos.bh);
658 650
659error_return: 651error_return:
660 sb->s_dirt = 1;
661 mutex_unlock(&sbi->s_alloc_mutex); 652 mutex_unlock(&sbi->s_alloc_mutex);
662 return; 653 return;
663} 654}
@@ -722,10 +713,8 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
722 713
723 brelse(epos.bh); 714 brelse(epos.bh);
724 715
725 if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) { 716 if (alloc_count)
726 mark_buffer_dirty(sbi->s_lvid_bh); 717 udf_add_free_space(sb, partition, -alloc_count);
727 sb->s_dirt = 1;
728 }
729 mutex_unlock(&sbi->s_alloc_mutex); 718 mutex_unlock(&sbi->s_alloc_mutex);
730 return alloc_count; 719 return alloc_count;
731} 720}
@@ -823,10 +812,8 @@ static int udf_table_new_block(struct super_block *sb,
823 udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); 812 udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
824 brelse(goal_epos.bh); 813 brelse(goal_epos.bh);
825 814
826 if (udf_add_free_space(sbi, partition, -1)) 815 udf_add_free_space(sb, partition, -1);
827 mark_buffer_dirty(sbi->s_lvid_bh);
828 816
829 sb->s_dirt = 1;
830 mutex_unlock(&sbi->s_alloc_mutex); 817 mutex_unlock(&sbi->s_alloc_mutex);
831 *err = 0; 818 *err = 0;
832 return newblock; 819 return newblock;