Hello, I am currently playing with snapshots and manual deduplication of files. During these tests I noticed the change of ctime and mtime in the snapshot after the deduplication with FILE_EXTENT_SAME. Does this happens on purpose? Otherwise I would like to have ctime and mtime left unmodified, because on a read only snapshot I cannot change them back after the ioctl call.
I attached a very basic patch, which illustrates my idea. Thanks, Gerhard
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9d46f60..975d207 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -59,7 +59,7 @@ #include "dev-replace.h" static int btrfs_clone(struct inode *src, struct inode *inode, - u64 off, u64 olen, u64 olen_aligned, u64 destoff); + u64 off, u64 olen, u64 olen_aligned, u64 destoff, int update_time); /* Mask out flags that are inappropriate for the given type of inode. */ static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) @@ -2683,7 +2683,7 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 len, ret = btrfs_cmp_data(src, loff, dst, dst_loff, len); if (ret == 0) - ret = btrfs_clone(src, dst, loff, len, len, dst_loff); + ret = btrfs_clone(src, dst, loff, len, len, dst_loff, /* update time */ 0); out_unlock: btrfs_double_unlock(src, loff, dst, dst_loff, len); @@ -2836,9 +2836,10 @@ out: * @olen_aligned: Block-aligned value of olen, extent_same uses * identical values here * @destoff: Offset within @inode to start clone + * @update_time: Should we update ctime and mtime of @inode? */ static int btrfs_clone(struct inode *src, struct inode *inode, - u64 off, u64 olen, u64 olen_aligned, u64 destoff) + u64 off, u64 olen, u64 olen_aligned, u64 destoff, int update_time) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_path *path = NULL; @@ -3081,8 +3082,10 @@ static int btrfs_clone(struct inode *src, struct inode *inode, btrfs_mark_buffer_dirty(leaf); btrfs_release_path(path); - inode_inc_iversion(inode); - inode->i_mtime = inode->i_ctime = CURRENT_TIME; + if (update_time) { + inode_inc_iversion(inode); + inode->i_mtime = inode->i_ctime = CURRENT_TIME; + } /* * we round up to the block size at eof when @@ -3227,7 +3230,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, lock_extent_range(src, off, len); - ret = btrfs_clone(src, inode, off, olen, len, destoff); + ret = btrfs_clone(src, inode, off, olen, len, destoff, /* update time */ 1); unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1); out_unlock: