diff --git a/include/ntfs-3g/device.h b/include/ntfs-3g/device.h index ac5ab789..ad34ac56 100644 --- a/include/ntfs-3g/device.h +++ b/include/ntfs-3g/device.h @@ -41,6 +41,7 @@ typedef enum { ND_ReadOnly, /* 1: Device is read-only. */ ND_Dirty, /* 1: Device is dirty, needs sync. */ ND_Block, /* 1: Device is a block device. */ + ND_Sync, /* 1: Device is mounted with "-o sync" */ } ntfs_device_state_bits; #define test_ndev_flag(nd, flag) test_bit(ND_##flag, (nd)->d_state) @@ -63,6 +64,10 @@ typedef enum { #define NDevSetBlock(nd) set_ndev_flag(nd, Block) #define NDevClearBlock(nd) clear_ndev_flag(nd, Block) +#define NDevSync(nd) test_ndev_flag(nd, Sync) +#define NDevSetSync(nd) set_ndev_flag(nd, Sync) +#define NDevClearSync(nd) clear_ndev_flag(nd, Sync) + /** * struct ntfs_device - * diff --git a/libntfs-3g/device.c b/libntfs-3g/device.c index d98a34aa..db840108 100644 --- a/libntfs-3g/device.c +++ b/libntfs-3g/device.c @@ -280,6 +280,9 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count, total = written; break; } + if (NDevSync(dev) && total && dops->sync(dev)) { + total--; /* on sync error, return partially written */ + } ret = total; out: return ret; diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index a39acd06..cfbf845f 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -217,6 +217,7 @@ typedef struct { BOOL silent; BOOL recover; BOOL hiberfile; + BOOL sync; BOOL debug; BOOL no_detach; BOOL blkdev; @@ -3671,6 +3672,8 @@ static int ntfs_open(const char *device) ntfs_log_perror("Failed to mount '%s'", device); goto err_out; } + if (ctx->sync && ctx->vol->dev) + NDevSetSync(ctx->vol->dev); if (ctx->compression) NVolSetCompression(ctx->vol); #ifdef HAVE_SETXATTR @@ -3893,6 +3896,12 @@ static char *parse_mount_options(const char *orig_opts) if (bogus_option_value(val, "remove_hiberfile")) goto err_exit; ctx->hiberfile = TRUE; + } else if (!strcmp(opt, "sync")) { + if (bogus_option_value(val, "sync")) + goto err_exit; + ctx->sync = TRUE; + if (strappend(&ret, "sync,")) + goto err_exit; } else if (!strcmp(opt, "locale")) { if (missing_option_value(val, "locale")) goto err_exit; diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 7c05fc07..cecdce77 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -177,6 +177,7 @@ typedef struct { BOOL silent; BOOL recover; BOOL hiberfile; + BOOL sync; BOOL debug; BOOL no_detach; BOOL blkdev; @@ -3628,6 +3629,8 @@ static int ntfs_open(const char *device) ntfs_log_perror("Failed to mount '%s'", device); goto err_out; } + if (ctx->sync && ctx->vol->dev) + NDevSetSync(ctx->vol->dev); if (ctx->compression) NVolSetCompression(ctx->vol); #ifdef HAVE_SETXATTR @@ -3843,6 +3846,12 @@ static char *parse_mount_options(const char *orig_opts) if (bogus_option_value(val, "remove_hiberfile")) goto err_exit; ctx->hiberfile = TRUE; + } else if (!strcmp(opt, "sync")) { + if (bogus_option_value(val, "sync")) + goto err_exit; + ctx->sync = TRUE; + if (strappend(&ret, "sync,")) + goto err_exit; } else if (!strcmp(opt, "locale")) { if (missing_option_value(val, "locale")) goto err_exit;