aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@tuxera.com>2010-11-23 08:37:57 -0500
committerChristoph Hellwig <hch@lst.de>2010-11-23 08:37:57 -0500
commit7dc4f001123f9ebe3b010a6c26acd18698ad205f (patch)
tree395164b35e03ba04c3ba2f9fd00b285bd52a8810
parent358f26d52680cb150907302d4334359de7dd2d59 (diff)
hfsplus: make sure sync writes out all metadata
hfsplus stores all metadata except for the volume headers in special inodes. While these are marked hashed and periodically written out by the flusher threads, we can't rely on that for sync. For the case of a data integrity sync the VM has life-lock avoidance code that avoids writing inodes again that are redirtied during the sync, which is something that can happen easily for hfsplus. So make sure we explicitly write out the metadata inodes at the beginning of hfsplus_sync_fs. Signed-off-by: Christoph Hellwig <hch@tuxera.com>
-rw-r--r--fs/hfsplus/super.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index fe8f7bffbea5..df6bea02b2b4 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -164,6 +164,22 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
164 164
165 sb->s_dirt = 0; 165 sb->s_dirt = 0;
166 166
167 /*
168 * Explicitly write out the special metadata inodes.
169 *
170 * While these special inodes are marked as hashed and written
171 * out peridocically by the flusher threads we redirty them
172 * during writeout of normal inodes, and thus the life lock
173 * prevents us from getting the latest state to disk.
174 */
175 error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping);
176 error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
177 if (!error)
178 error = error2;
179 error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
180 if (!error)
181 error = error2;
182
167 mutex_lock(&sbi->vh_mutex); 183 mutex_lock(&sbi->vh_mutex);
168 mutex_lock(&sbi->alloc_mutex); 184 mutex_lock(&sbi->alloc_mutex);
169 vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); 185 vhdr->free_blocks = cpu_to_be32(sbi->free_blocks);
@@ -176,9 +192,11 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
176 write_backup = 1; 192 write_backup = 1;
177 } 193 }
178 194
179 error = hfsplus_submit_bio(sb->s_bdev, 195 error2 = hfsplus_submit_bio(sb->s_bdev,
180 sbi->part_start + HFSPLUS_VOLHEAD_SECTOR, 196 sbi->part_start + HFSPLUS_VOLHEAD_SECTOR,
181 sbi->s_vhdr, WRITE_SYNC); 197 sbi->s_vhdr, WRITE_SYNC);
198 if (!error)
199 error = error2;
182 if (!write_backup) 200 if (!write_backup)
183 goto out; 201 goto out;
184 202