aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r--fs/hfsplus/super.c48
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;
190out:
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
201static void hfsplus_write_super(struct super_block *sb) 196static 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;