Commit 7dc4f001123f9ebe3b010a6c26acd18698ad205f

Authored by Christoph Hellwig
Committed by Christoph Hellwig
1 parent 358f26d526

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>

Showing 1 changed file with 19 additions and 1 deletions Side-by-side Diff

... ... @@ -164,6 +164,22 @@
164 164  
165 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 183 mutex_lock(&sbi->vh_mutex);
168 184 mutex_lock(&sbi->alloc_mutex);
169 185 vhdr->free_blocks = cpu_to_be32(sbi->free_blocks);
170 186  
... ... @@ -176,9 +192,11 @@
176 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 196 sbi->part_start + HFSPLUS_VOLHEAD_SECTOR,
181 197 sbi->s_vhdr, WRITE_SYNC);
  198 + if (!error)
  199 + error = error2;
182 200 if (!write_backup)
183 201 goto out;
184 202