From a7e4d503e2dd29892e2195d4ebb48c29ad39c7fa Mon Sep 17 00:00:00 2001 From: szaka Date: Thu, 9 Aug 2007 14:11:54 +0000 Subject: [PATCH] fix: rename may updated mtime for some files/dirs (Wayne Sherman, Szaka) --- include/ntfs-3g/inode.h | 6 ++++++ libntfs-3g/inode.c | 2 +- src/ntfs-3g.c | 25 ++++++++++++++++++++----- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/ntfs-3g/inode.h b/include/ntfs-3g/inode.h index 7867d235..3ff15f43 100644 --- a/include/ntfs-3g/inode.h +++ b/include/ntfs-3g/inode.h @@ -48,6 +48,7 @@ typedef enum { mft record and then to disk. */ NI_FileNameDirty, /* 1: FILE_NAME attributes need to be updated in the index. */ + NI_NoMtimeUpdate, /* 1: Don't update modifiction time. */ } ntfs_inode_state_bits; #define test_nino_flag(ni, flag) test_bit(NI_##flag, (ni)->state) @@ -96,6 +97,11 @@ typedef enum { #define NInoFileNameTestAndClearDirty(ni) \ test_and_clear_nino_flag(ni, FileNameDirty) +#define NInoNoMtimeUpdate(ni) test_nino_flag(ni, NoMtimeUpdate) +#define NInoSetNoMtimeUpdate(ni) set_nino_flag(ni, NoMtimeUpdate) +#define NInoClearNoMtimeUpdate(ni) clear_nino_flag(ni, NoMtimeUpdate) +#define NInoMtimeUpdate(ni) (!NInoNoMtimeUpdate(ni)) + /** * struct _ntfs_inode - The NTFS in-memory inode structure. * diff --git a/libntfs-3g/inode.c b/libntfs-3g/inode.c index c4cb0c59..446adda5 100644 --- a/libntfs-3g/inode.c +++ b/libntfs-3g/inode.c @@ -1121,7 +1121,7 @@ void ntfs_inode_update_atime(ntfs_inode *ni) */ void ntfs_inode_update_time(ntfs_inode *ni) { - if (!NVolReadOnly(ni->vol) && + if (!NVolReadOnly(ni->vol) && NInoMtimeUpdate(ni) && (ni->mft_no >= FILE_first_user || ni->mft_no == FILE_root)) { time_t now; diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 0c4b369d..b65f5f91 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -951,7 +951,13 @@ static int ntfs_fuse_symlink(const char *to, const char *from) return ntfs_fuse_create(from, S_IFLNK, 0, to); } -static int ntfs_fuse_link(const char *old_path, const char *new_path) +/** + * NOTE: About the role of mtime: during rename(3), which is currently + * implemented by the help of link() operations, modification time mustn't + * be updated, so we NInoSetNoMtimeUpdate() such inodes after they are opened. + * This is not very nice itself but it may be eliminated, in time. + */ +static int ntfs_fuse_ln(const char *old_path, const char *new_path, int mtime) { char *name; ntfschar *uname = NULL; @@ -972,6 +978,10 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path) res = -errno; goto exit; } + + if (!mtime) + NInoSetNoMtimeUpdate(ni); + /* Generate unicode filename. */ name = strrchr(path, '/'); name++; @@ -1005,6 +1015,11 @@ exit: return res; } +static int ntfs_fuse_link(const char *old_path, const char *new_path) +{ + return ntfs_fuse_ln(old_path, new_path, 1); +} + static int ntfs_fuse_rm(const char *org_path) { char *name; @@ -1098,14 +1113,14 @@ static int ntfs_fuse_safe_rename(const char *old_path, ntfs_log_trace("Entering\n"); - ret = ntfs_fuse_link(new_path, tmp); + ret = ntfs_fuse_ln(new_path, tmp, 0); if (ret) return ret; ret = ntfs_fuse_unlink(new_path); if (!ret) { - ret = ntfs_fuse_link(old_path, new_path); + ret = ntfs_fuse_ln(old_path, new_path, 0); if (ret) goto restore; @@ -1119,7 +1134,7 @@ static int ntfs_fuse_safe_rename(const char *old_path, goto cleanup; restore: - if (ntfs_fuse_link(tmp, new_path)) { + if (ntfs_fuse_ln(tmp, new_path, 0)) { err: ntfs_log_perror("Rename failed. Existing file '%s' was renamed " "to '%s'", new_path, tmp); @@ -1188,7 +1203,7 @@ static int ntfs_fuse_rename(const char *old_path, const char *new_path) goto out; } - ret = ntfs_fuse_link(old_path, new_path); + ret = ntfs_fuse_ln(old_path, new_path, 0); if (ret) goto out;