Commit 34a2d313 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Christoph Hellwig

hfsplus: flush disk caches in sync and fsync

Flush the disk cache in fsync and sync to make sure data actually is
on disk on completion of these system calls.  There is a nobarrier
mount option to disable this behaviour.  It's slightly misnamed now
that barrier actually are gone, but it matches the name used by all
major filesystems.
Signed-off-by: default avatarChristoph Hellwig <hch@tuxera.com>
parent e3494705
...@@ -156,6 +156,7 @@ struct hfsplus_sb_info { ...@@ -156,6 +156,7 @@ struct hfsplus_sb_info {
#define HFSPLUS_SB_FORCE 2 #define HFSPLUS_SB_FORCE 2
#define HFSPLUS_SB_HFSX 3 #define HFSPLUS_SB_HFSX 3
#define HFSPLUS_SB_CASEFOLD 4 #define HFSPLUS_SB_CASEFOLD 4
#define HFSPLUS_SB_NOBARRIER 5
static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb) static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
{ {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Inode handling routines * Inode handling routines
*/ */
#include <linux/blkdev.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
...@@ -334,6 +335,9 @@ int hfsplus_file_fsync(struct file *file, int datasync) ...@@ -334,6 +335,9 @@ int hfsplus_file_fsync(struct file *file, int datasync)
error = error2; error = error2;
} }
if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
return error; return error;
} }
......
...@@ -23,6 +23,7 @@ enum { ...@@ -23,6 +23,7 @@ enum {
opt_umask, opt_uid, opt_gid, opt_umask, opt_uid, opt_gid,
opt_part, opt_session, opt_nls, opt_part, opt_session, opt_nls,
opt_nodecompose, opt_decompose, opt_nodecompose, opt_decompose,
opt_barrier, opt_nobarrier,
opt_force, opt_err opt_force, opt_err
}; };
...@@ -37,6 +38,8 @@ static const match_table_t tokens = { ...@@ -37,6 +38,8 @@ static const match_table_t tokens = {
{ opt_nls, "nls=%s" }, { opt_nls, "nls=%s" },
{ opt_decompose, "decompose" }, { opt_decompose, "decompose" },
{ opt_nodecompose, "nodecompose" }, { opt_nodecompose, "nodecompose" },
{ opt_barrier, "barrier" },
{ opt_nobarrier, "nobarrier" },
{ opt_force, "force" }, { opt_force, "force" },
{ opt_err, NULL } { opt_err, NULL }
}; };
...@@ -174,6 +177,12 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) ...@@ -174,6 +177,12 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
case opt_nodecompose: case opt_nodecompose:
set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags); set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
break; break;
case opt_barrier:
clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
break;
case opt_nobarrier:
set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags);
break;
case opt_force: case opt_force:
set_bit(HFSPLUS_SB_FORCE, &sbi->flags); set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
break; break;
...@@ -212,5 +221,7 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt) ...@@ -212,5 +221,7 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt)
seq_printf(seq, ",nls=%s", sbi->nls->charset); seq_printf(seq, ",nls=%s", sbi->nls->charset);
if (test_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags)) if (test_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags))
seq_printf(seq, ",nodecompose"); seq_printf(seq, ",nodecompose");
if (test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
seq_printf(seq, ",nobarrier");
return 0; return 0;
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/blkdev.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vfs.h> #include <linux/vfs.h>
...@@ -212,6 +213,10 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) ...@@ -212,6 +213,10 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
out: out:
mutex_unlock(&sbi->alloc_mutex); mutex_unlock(&sbi->alloc_mutex);
mutex_unlock(&sbi->vh_mutex); mutex_unlock(&sbi->vh_mutex);
if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags))
blkdev_issue_flush(sb->s_bdev, GFP_KERNEL, NULL);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment