aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/inode.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@tuxera.com>2010-11-23 08:38:15 -0500
committerChristoph Hellwig <hch@lst.de>2010-11-23 08:38:15 -0500
commite34947056076ca5467ee8256d2d9cbc594a79b37 (patch)
treec1b70f51c1e4bc38e0b0389224862afe26c5720f /fs/hfsplus/inode.c
parentb33b7921db14abcd10c30d0ccfc68e364f5ef7fe (diff)
hfsplus: optimize fsync
Avoid doing unessecary work in fsync. Do nothing unless the inode was marked dirty, and only write the various metadata inodes out if they contain any dirty state from this inode. This is archived by adding three new dirty bits to the hfsplus-specific inode which are set in the correct places. Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs/hfsplus/inode.c')
-rw-r--r--fs/hfsplus/inode.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 0946e2cdca5e..bf6535b73261 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -307,8 +307,9 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
307int hfsplus_file_fsync(struct file *file, int datasync) 307int hfsplus_file_fsync(struct file *file, int datasync)
308{ 308{
309 struct inode *inode = file->f_mapping->host; 309 struct inode *inode = file->f_mapping->host;
310 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
310 struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); 311 struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
311 int error, error2; 312 int error = 0, error2;
312 313
313 /* 314 /*
314 * Sync inode metadata into the catalog and extent trees. 315 * Sync inode metadata into the catalog and extent trees.
@@ -318,13 +319,21 @@ int hfsplus_file_fsync(struct file *file, int datasync)
318 /* 319 /*
319 * And explicitly write out the btrees. 320 * And explicitly write out the btrees.
320 */ 321 */
321 error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); 322 if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags))
322 error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); 323 error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping);
323 if (!error) 324
324 error = error2; 325 if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) {
325 error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); 326 error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping);
326 if (!error) 327 if (!error)
327 error = error2; 328 error = error2;
329 }
330
331 if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) {
332 error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping);
333 if (!error)
334 error = error2;
335 }
336
328 return error; 337 return error;
329} 338}
330 339
@@ -590,6 +599,8 @@ int hfsplus_cat_write_inode(struct inode *inode)
590 hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, 599 hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
591 sizeof(struct hfsplus_cat_file)); 600 sizeof(struct hfsplus_cat_file));
592 } 601 }
602
603 set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
593out: 604out:
594 hfs_find_exit(&fd); 605 hfs_find_exit(&fd);
595 return 0; 606 return 0;