diff options
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r-- | fs/hfsplus/super.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 6a2349058618..fe8f7bffbea5 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -157,45 +157,40 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) | |||
157 | { | 157 | { |
158 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | 158 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); |
159 | struct hfsplus_vh *vhdr = sbi->s_vhdr; | 159 | struct hfsplus_vh *vhdr = sbi->s_vhdr; |
160 | int write_backup = 0; | ||
161 | int error, error2; | ||
160 | 162 | ||
161 | dprint(DBG_SUPER, "hfsplus_write_super\n"); | 163 | dprint(DBG_SUPER, "hfsplus_write_super\n"); |
162 | 164 | ||
163 | mutex_lock(&sbi->vh_mutex); | ||
164 | mutex_lock(&sbi->alloc_mutex); | ||
165 | sb->s_dirt = 0; | 165 | sb->s_dirt = 0; |
166 | 166 | ||
167 | mutex_lock(&sbi->vh_mutex); | ||
168 | mutex_lock(&sbi->alloc_mutex); | ||
167 | vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); | 169 | vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); |
168 | vhdr->next_cnid = cpu_to_be32(sbi->next_cnid); | 170 | vhdr->next_cnid = cpu_to_be32(sbi->next_cnid); |
169 | vhdr->folder_count = cpu_to_be32(sbi->folder_count); | 171 | vhdr->folder_count = cpu_to_be32(sbi->folder_count); |
170 | vhdr->file_count = cpu_to_be32(sbi->file_count); | 172 | vhdr->file_count = cpu_to_be32(sbi->file_count); |
171 | 173 | ||
172 | mark_buffer_dirty(sbi->s_vhbh); | ||
173 | if (test_and_clear_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags)) { | 174 | if (test_and_clear_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags)) { |
174 | if (sbi->sect_count) { | 175 | memcpy(sbi->s_backup_vhdr, sbi->s_vhdr, sizeof(*sbi->s_vhdr)); |
175 | struct buffer_head *bh; | 176 | write_backup = 1; |
176 | u32 block, offset; | ||
177 | |||
178 | block = sbi->blockoffset; | ||
179 | block += (sbi->sect_count - 2) >> (sb->s_blocksize_bits - 9); | ||
180 | offset = ((sbi->sect_count - 2) << 9) & (sb->s_blocksize - 1); | ||
181 | printk(KERN_DEBUG "hfs: backup: %u,%u,%u,%u\n", | ||
182 | sbi->blockoffset, sbi->sect_count, | ||
183 | block, offset); | ||
184 | bh = sb_bread(sb, block); | ||
185 | if (bh) { | ||
186 | vhdr = (struct hfsplus_vh *)(bh->b_data + offset); | ||
187 | if (be16_to_cpu(vhdr->signature) == HFSPLUS_VOLHEAD_SIG) { | ||
188 | memcpy(vhdr, sbi->s_vhdr, sizeof(*vhdr)); | ||
189 | mark_buffer_dirty(bh); | ||
190 | brelse(bh); | ||
191 | } else | ||
192 | printk(KERN_WARNING "hfs: backup not found!\n"); | ||
193 | } | ||
194 | } | ||
195 | } | 177 | } |
178 | |||
179 | error = hfsplus_submit_bio(sb->s_bdev, | ||
180 | sbi->part_start + HFSPLUS_VOLHEAD_SECTOR, | ||
181 | sbi->s_vhdr, WRITE_SYNC); | ||
182 | if (!write_backup) | ||
183 | goto out; | ||
184 | |||
185 | error2 = hfsplus_submit_bio(sb->s_bdev, | ||
186 | sbi->part_start + sbi->sect_count - 2, | ||
187 | sbi->s_backup_vhdr, WRITE_SYNC); | ||
188 | if (!error) | ||
189 | error2 = error; | ||
190 | out: | ||
196 | mutex_unlock(&sbi->alloc_mutex); | 191 | mutex_unlock(&sbi->alloc_mutex); |
197 | mutex_unlock(&sbi->vh_mutex); | 192 | mutex_unlock(&sbi->vh_mutex); |
198 | return 0; | 193 | return error; |
199 | } | 194 | } |
200 | 195 | ||
201 | static void hfsplus_write_super(struct super_block *sb) | 196 | static void hfsplus_write_super(struct super_block *sb) |
@@ -229,7 +224,8 @@ static void hfsplus_put_super(struct super_block *sb) | |||
229 | hfs_btree_close(sbi->ext_tree); | 224 | hfs_btree_close(sbi->ext_tree); |
230 | iput(sbi->alloc_file); | 225 | iput(sbi->alloc_file); |
231 | iput(sbi->hidden_dir); | 226 | iput(sbi->hidden_dir); |
232 | brelse(sbi->s_vhbh); | 227 | kfree(sbi->s_vhdr); |
228 | kfree(sbi->s_backup_vhdr); | ||
233 | unload_nls(sbi->nls); | 229 | unload_nls(sbi->nls); |
234 | kfree(sb->s_fs_info); | 230 | kfree(sb->s_fs_info); |
235 | sb->s_fs_info = NULL; | 231 | sb->s_fs_info = NULL; |