diff --git a/src/ntfs-3g.8.in b/src/ntfs-3g.8.in index c4824a9a..0dcf5510 100644 --- a/src/ntfs-3g.8.in +++ b/src/ntfs-3g.8.in @@ -99,7 +99,8 @@ present. The value is given in octal. The default value is 0 which means full access to everybody. .TP .B ro -Mount filesystem read\-only. +Mount filesystem read\-only. Useful if Windows is hibernated or the +NTFS journal file is unclean. .TP .BI locale= value This option can be useful if your language specific locale environment @@ -113,6 +114,29 @@ Force the mounting even if the NTFS logfile is unclean. The logfile will be unconditionally cleared. Use this option with caution and for your own responsibility. .TP +.B atime, noatime, relatime +The +.B atime +option updates inode access time for each access. + +The +.B noatime +option disables inode access time updates which can speed up +file operations and prevent sleeping (notebook) disks spinning +up too often thus saving energy and disk lifetime. + +The +.B relatime +option is very similar to +.B noatime. +It updates inode access times relative to modify or change time. +The access time is only updated if the previous access time was earlier +than the current modify or change time. Unlike +.B noatime +this option doesn't break applications that need to know +if a file has been read since the last time it was modified. +This is the default behaviour. +.TP .B show_sys_files Show the system files in directory listings. Otherwise the default behaviour is to hide the system files. diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index bd6a6ce7..f0be4709 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -92,6 +92,12 @@ typedef enum { FSTYPE_FUSEBLK } fuse_fstype; +typedef enum { + ATIME_ENABLED, + ATIME_DISABLED, + ATIME_RELATIVE +} ntfs_atime_t; + typedef struct { fuse_fill_dir_t filler; void *buf; @@ -110,12 +116,12 @@ typedef struct { unsigned int fmask; unsigned int dmask; ntfs_fuse_streams_interface streams; + ntfs_atime_t atime; BOOL ro; BOOL show_sys_files; BOOL silent; BOOL force; BOOL debug; - BOOL noatime; BOOL no_detach; BOOL blkdev; BOOL mounted; @@ -170,8 +176,12 @@ static int ntfs_fuse_is_named_data_stream(const char *path) static void ntfs_fuse_update_times(ntfs_inode *ni, ntfs_time_update_flags mask) { - if (ctx->noatime) + if (ctx->atime == ATIME_DISABLED) mask &= ~NTFS_UPDATE_ATIME; + else if (ctx->atime == ATIME_RELATIVE && mask == NTFS_UPDATE_ATIME && + ni->last_access_time >= ni->last_data_change_time && + ni->last_access_time >= ni->last_mft_change_time) + return; ntfs_inode_update_times(ni, mask); } @@ -1676,6 +1686,8 @@ static char *parse_mount_options(const char *orig_opts) ctx->silent = TRUE; + ctx->atime = ATIME_RELATIVE; + s = options; while (s && *s && (val = strsep(&s, ","))) { opt = strsep(&val, "="); @@ -1693,8 +1705,21 @@ static char *parse_mount_options(const char *orig_opts) "have value.\n"); goto err_exit; } - ctx->noatime = TRUE; - strcat(ret, "noatime,"); + ctx->atime = ATIME_DISABLED; + } else if (!strcmp(opt, "atime")) { + if (val) { + ntfs_log_error("'atime' option should not " + "have value.\n"); + goto err_exit; + } + ctx->atime = ATIME_ENABLED; + } else if (!strcmp(opt, "relatime")) { + if (val) { + ntfs_log_error("'relatime' option should not " + "have value.\n"); + goto err_exit; + } + ctx->atime = ATIME_RELATIVE; } else if (!strcmp(opt, "fake_rw")) { if (val) { ntfs_log_error("'fake_rw' option should not " @@ -1847,6 +1872,14 @@ static char *parse_mount_options(const char *orig_opts) strcat(ret, def_opts); if (default_permissions) strcat(ret, "default_permissions,"); + + if (ctx->atime == ATIME_RELATIVE) + strcat(ret, "relatime,"); + else if (ctx->atime == ATIME_ENABLED) + strcat(ret, "atime,"); + else + strcat(ret, "noatime,"); + strcat(ret, "fsname="); strcat(ret, opts.device); exit: