aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/balloc.c37
-rw-r--r--fs/udf/ialloc.c5
-rw-r--r--fs/udf/super.c44
-rw-r--r--fs/udf/udf_sb.h2
-rw-r--r--fs/udf/udfdecl.h11
5 files changed, 52 insertions, 47 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;
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 6eb279d5f4fb..c10fa39f97e2 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -49,8 +49,7 @@ void udf_free_inode(struct inode *inode)
49 le32_add_cpu(&lvidiu->numDirs, -1); 49 le32_add_cpu(&lvidiu->numDirs, -1);
50 else 50 else
51 le32_add_cpu(&lvidiu->numFiles, -1); 51 le32_add_cpu(&lvidiu->numFiles, -1);
52 52 udf_updated_lvid(sb);
53 mark_buffer_dirty(sbi->s_lvid_bh);
54 } 53 }
55 mutex_unlock(&sbi->s_alloc_mutex); 54 mutex_unlock(&sbi->s_alloc_mutex);
56 55
@@ -122,7 +121,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
122 if (!(++uniqueID & 0x00000000FFFFFFFFUL)) 121 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
123 uniqueID += 16; 122 uniqueID += 16;
124 lvhd->uniqueID = cpu_to_le64(uniqueID); 123 lvhd->uniqueID = cpu_to_le64(uniqueID);
125 mark_buffer_dirty(sbi->s_lvid_bh); 124 udf_updated_lvid(sb);
126 } 125 }
127 mutex_unlock(&sbi->s_alloc_mutex); 126 mutex_unlock(&sbi->s_alloc_mutex);
128 inode->i_mode = mode; 127 inode->i_mode = mode;
diff --git a/fs/udf/super.c b/fs/udf/super.c
index cae079eb5dd9..72348cc855a4 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -81,7 +81,7 @@ static char error_buf[1024];
81/* These are the "meat" - everything else is stuffing */ 81/* These are the "meat" - everything else is stuffing */
82static int udf_fill_super(struct super_block *, void *, int); 82static int udf_fill_super(struct super_block *, void *, int);
83static void udf_put_super(struct super_block *); 83static void udf_put_super(struct super_block *);
84static void udf_write_super(struct super_block *); 84static int udf_sync_fs(struct super_block *, int);
85static int udf_remount_fs(struct super_block *, int *, char *); 85static int udf_remount_fs(struct super_block *, int *, char *);
86static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); 86static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
87static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, 87static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *,
@@ -178,7 +178,7 @@ static const struct super_operations udf_sb_ops = {
178 .delete_inode = udf_delete_inode, 178 .delete_inode = udf_delete_inode,
179 .clear_inode = udf_clear_inode, 179 .clear_inode = udf_clear_inode,
180 .put_super = udf_put_super, 180 .put_super = udf_put_super,
181 .write_super = udf_write_super, 181 .sync_fs = udf_sync_fs,
182 .statfs = udf_statfs, 182 .statfs = udf_statfs,
183 .remount_fs = udf_remount_fs, 183 .remount_fs = udf_remount_fs,
184 .show_options = udf_show_options, 184 .show_options = udf_show_options,
@@ -553,17 +553,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
553 return 1; 553 return 1;
554} 554}
555 555
556static void udf_write_super(struct super_block *sb)
557{
558 lock_kernel();
559
560 if (!(sb->s_flags & MS_RDONLY))
561 udf_open_lvid(sb);
562 sb->s_dirt = 0;
563
564 unlock_kernel();
565}
566
567static int udf_remount_fs(struct super_block *sb, int *flags, char *options) 556static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
568{ 557{
569 struct udf_options uopt; 558 struct udf_options uopt;
@@ -1753,9 +1742,9 @@ static void udf_open_lvid(struct super_block *sb)
1753 struct buffer_head *bh = sbi->s_lvid_bh; 1742 struct buffer_head *bh = sbi->s_lvid_bh;
1754 struct logicalVolIntegrityDesc *lvid; 1743 struct logicalVolIntegrityDesc *lvid;
1755 struct logicalVolIntegrityDescImpUse *lvidiu; 1744 struct logicalVolIntegrityDescImpUse *lvidiu;
1745
1756 if (!bh) 1746 if (!bh)
1757 return; 1747 return;
1758
1759 lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1748 lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
1760 lvidiu = udf_sb_lvidiu(sbi); 1749 lvidiu = udf_sb_lvidiu(sbi);
1761 1750
@@ -1763,7 +1752,7 @@ static void udf_open_lvid(struct super_block *sb)
1763 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1752 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1764 udf_time_to_disk_stamp(&lvid->recordingDateAndTime, 1753 udf_time_to_disk_stamp(&lvid->recordingDateAndTime,
1765 CURRENT_TIME); 1754 CURRENT_TIME);
1766 lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN; 1755 lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
1767 1756
1768 lvid->descTag.descCRC = cpu_to_le16( 1757 lvid->descTag.descCRC = cpu_to_le16(
1769 crc_itu_t(0, (char *)lvid + sizeof(struct tag), 1758 crc_itu_t(0, (char *)lvid + sizeof(struct tag),
@@ -1771,6 +1760,7 @@ static void udf_open_lvid(struct super_block *sb)
1771 1760
1772 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); 1761 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
1773 mark_buffer_dirty(bh); 1762 mark_buffer_dirty(bh);
1763 sbi->s_lvid_dirty = 0;
1774} 1764}
1775 1765
1776static void udf_close_lvid(struct super_block *sb) 1766static void udf_close_lvid(struct super_block *sb)
@@ -1784,10 +1774,6 @@ static void udf_close_lvid(struct super_block *sb)
1784 return; 1774 return;
1785 1775
1786 lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1776 lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
1787
1788 if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN)
1789 return;
1790
1791 lvidiu = udf_sb_lvidiu(sbi); 1777 lvidiu = udf_sb_lvidiu(sbi);
1792 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1778 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1793 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1779 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1806,6 +1792,7 @@ static void udf_close_lvid(struct super_block *sb)
1806 1792
1807 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); 1793 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
1808 mark_buffer_dirty(bh); 1794 mark_buffer_dirty(bh);
1795 sbi->s_lvid_dirty = 0;
1809} 1796}
1810 1797
1811static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) 1798static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
@@ -2092,6 +2079,25 @@ static void udf_put_super(struct super_block *sb)
2092 sb->s_fs_info = NULL; 2079 sb->s_fs_info = NULL;
2093} 2080}
2094 2081
2082static int udf_sync_fs(struct super_block *sb, int wait)
2083{
2084 struct udf_sb_info *sbi = UDF_SB(sb);
2085
2086 mutex_lock(&sbi->s_alloc_mutex);
2087 if (sbi->s_lvid_dirty) {
2088 /*
2089 * Blockdevice will be synced later so we don't have to submit
2090 * the buffer for IO
2091 */
2092 mark_buffer_dirty(sbi->s_lvid_bh);
2093 sb->s_dirt = 0;
2094 sbi->s_lvid_dirty = 0;
2095 }
2096 mutex_unlock(&sbi->s_alloc_mutex);
2097
2098 return 0;
2099}
2100
2095static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) 2101static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
2096{ 2102{
2097 struct super_block *sb = dentry->d_sb; 2103 struct super_block *sb = dentry->d_sb;
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 46fea3ea70a9..d113b72c2768 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -148,6 +148,8 @@ struct udf_sb_info {
148 struct inode *s_vat_inode; 148 struct inode *s_vat_inode;
149 149
150 struct mutex s_alloc_mutex; 150 struct mutex s_alloc_mutex;
151 /* Protected by s_alloc_mutex */
152 unsigned int s_lvid_dirty;
151}; 153};
152 154
153static inline struct udf_sb_info *UDF_SB(struct super_block *sb) 155static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 9a2a9b61413e..cac51b77a5d1 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -111,6 +111,17 @@ struct extent_position {
111 111
112/* super.c */ 112/* super.c */
113extern void udf_warning(struct super_block *, const char *, const char *, ...); 113extern void udf_warning(struct super_block *, const char *, const char *, ...);
114static inline void udf_updated_lvid(struct super_block *sb)
115{
116 struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh;
117
118 BUG_ON(!bh);
119 WARN_ON_ONCE(((struct logicalVolIntegrityDesc *)
120 bh->b_data)->integrityType !=
121 cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN));
122 sb->s_dirt = 1;
123 UDF_SB(sb)->s_lvid_dirty = 1;
124}
114 125
115/* namei.c */ 126/* namei.c */
116extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, 127extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,