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: