diff mbox

[2/2] ext4: update donor file's ctime/mtime

Message ID 4ACD9D04.40503@sx.jp.nec.com
State New, archived
Headers show

Commit Message

Kazuya Mio Oct. 8, 2009, 8:04 a.m. UTC
EXT4_IOC_MOVE_EXT changes donor file data, but doesn't update ctime/mtime.
This patch fixes this problem.

Signed-off-by: Kazuya Mio <k-mio@sx.jp.nec.com>
---

 move_extent.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Andreas Dilger Oct. 9, 2009, 5:20 p.m. UTC | #1
On 8-Oct-09, at 02:04, Kazuya Mio wrote:

> EXT4_IOC_MOVE_EXT changes donor file data, but doesn't update ctime/ 
> mtime.
> This patch fixes this problem.

I would argue that just migrating the file data shouldn't update the  
ctime/mtime.
Those are used to determine if the file has changed in some way,  
usually for the
purpose of backup.  Migrating the data does not change anything from  
the user-space
POV and shouldn't force a new backup of the file.
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kazuya Mio Oct. 14, 2009, 1:49 a.m. UTC | #2
2009/10/10 2:20, Andreas Dilger wrote::
> 
> On 8-Oct-09, at 02:04, Kazuya Mio wrote:
> 
>> EXT4_IOC_MOVE_EXT changes donor file data, but doesn't update 
>> ctime/mtime.
>> This patch fixes this problem.
> 
> I would argue that just migrating the file data shouldn't update the 
> ctime/mtime.
> Those are used to determine if the file has changed in some way, usually 
> for the
> purpose of backup.  Migrating the data does not change anything from the 
> user-space
> POV and shouldn't force a new backup of the file.

EXT4_IOC_MOVE_EXT always changes the original actual contents of donor file
if orig file and donor file aren't the same. It may be that some of
user-space implementations hide such a changing. For example, e4defrag
unlinks the donor file, and removes it by decreasing reference count after
calling EXT4_IOC_MOVE_EXT. But from the ioctl point of view,
EXT4_IOC_MOVE_EXT doesn't know whether donor file will be removed or not,
so I think we should update ctime/mtime.

Am I missing something?

Regards,
Kazuya Mio
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andreas Dilger Oct. 14, 2009, 6:10 p.m. UTC | #3
On 13-Oct-09, at 18:49, Kazuya Mio wrote:
> 2009/10/10 2:20, Andreas Dilger wrote::
>>
>> On 8-Oct-09, at 02:04, Kazuya Mio wrote:
>>
>>> EXT4_IOC_MOVE_EXT changes donor file data, but doesn't update
>>> ctime/mtime.  This patch fixes this problem.
>>
>> I would argue that just migrating the file data shouldn't update the
>> ctime/mtime.  Those are used to determine if the file has changed  
>> in some way, usually for the purpose of backup.  Migrating the data  
>> does not change anything from user-space POV and shouldn't force a  
>> new backup of the file.
>
> EXT4_IOC_MOVE_EXT always changes the original actual contents of  
> donor file
> if orig file and donor file aren't the same. It may be that some of
> user-space implementations hide such a changing. For example, e4defrag
> unlinks the donor file, and removes it by decreasing reference count  
> after
> calling EXT4_IOC_MOVE_EXT. But from the ioctl point of view,
> EXT4_IOC_MOVE_EXT doesn't know whether donor file will be removed or  
> not,
> so I think we should update ctime/mtime.

Maybe I am confused.  Is EXT4_IOC_MOVE_EXT used for file  
defragmentation?
I thought the goal of this ioctl was to copy the data from the donor  
inode
to the target inode (using a new allocation in the target inode), and  
then
once the whole donor file had been copied (defragmented) the target  
extents
replace the entire donor file's extents?

In this model it would be OK to change the mtime/ctime of the _target_  
file,
but when these extents move back to the donor file the mtime/ctime of  
the donor
file should not be changed, I think, so that it does not force a full  
backup.

If the caller has done something to change the actual data in the  
donor file
it can always use utimes() to update the ctime/mtime, but it is not  
possible
for userspace to revert the ctime after it has changed.

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Greg Freemyer Oct. 14, 2009, 9:19 p.m. UTC | #4
On Wed, Oct 14, 2009 at 2:10 PM, Andreas Dilger <adilger@sun.com> wrote:
> On 13-Oct-09, at 18:49, Kazuya Mio wrote:
>>
>> 2009/10/10 2:20, Andreas Dilger wrote::
>>>
>>> On 8-Oct-09, at 02:04, Kazuya Mio wrote:
>>>
>>>> EXT4_IOC_MOVE_EXT changes donor file data, but doesn't update
>>>> ctime/mtime.  This patch fixes this problem.
>>>
>>> I would argue that just migrating the file data shouldn't update the
>>> ctime/mtime.  Those are used to determine if the file has changed in some
>>> way, usually for the purpose of backup.  Migrating the data does not change
>>> anything from user-space POV and shouldn't force a new backup of the file.
>>
>> EXT4_IOC_MOVE_EXT always changes the original actual contents of donor
>> file
>> if orig file and donor file aren't the same. It may be that some of
>> user-space implementations hide such a changing. For example, e4defrag
>> unlinks the donor file, and removes it by decreasing reference count after
>> calling EXT4_IOC_MOVE_EXT. But from the ioctl point of view,
>> EXT4_IOC_MOVE_EXT doesn't know whether donor file will be removed or not,
>> so I think we should update ctime/mtime.
>
> Maybe I am confused.  Is EXT4_IOC_MOVE_EXT used for file defragmentation?
> I thought the goal of this ioctl was to copy the data from the donor inode
> to the target inode (using a new allocation in the target inode), and then
> once the whole donor file had been copied (defragmented) the target extents
> replace the entire donor file's extents?
>
> In this model it would be OK to change the mtime/ctime of the _target_ file,
> but when these extents move back to the donor file the mtime/ctime of the
> donor
> file should not be changed, I think, so that it does not force a full
> backup.
>
> If the caller has done something to change the actual data in the donor file
> it can always use utimes() to update the ctime/mtime, but it is not possible
> for userspace to revert the ctime after it has changed.
>
> Cheers, Andreas
> --
> Andreas Dilger
> Sr. Staff Engineer, Lustre Group
> Sun Microsystems of Canada, Inc.

You have it backwards.

The target file is the fragmented file containing good data.  ie. It
is the target of the defragmentation process.

The donor file starts out as fallocated file with no valid data in it,
but the data blocks are less fragmented than the target hopefully.

The target file ends up using the data blocks provided by the donor,
but with the target files original data in them.

What the donor has at the end of the process, I don't know for sure.
I assume it is a zero length file that is in need of being deleted.
Having the donor's timestamps seems technically correct, but of little
real world consequence.  Or maybe there will eventually be a use case
that reuses the donor file for some purpose.

Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index e2e99fd..1cb2609 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -1210,6 +1210,7 @@  ext4_move_extents(struct file *o_filp, struct file *d_filp,
 	ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
 	ext4_lblk_t rest_blocks;
 	pgoff_t orig_page_offset = 0, seq_end_page;
+	handle_t *handle;
 	int ret1, ret2, depth, last_extent = 0;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 	int data_offset_in_page;
@@ -1406,6 +1407,25 @@  ext4_move_extents(struct file *o_filp, struct file *d_filp,
 
 	}
 out:
+	/*
+	 * Note that ctime/mtime will not be updated if power failure is
+	 * detected during block replacing.
+	 */
+	if (*moved_len) {
+		handle = ext4_journal_start(donor_inode, 1);
+		if (IS_ERR(handle))
+			ret2 = PTR_ERR(handle);
+		else {
+			donor_inode->i_ctime = donor_inode->i_mtime =
+					ext4_current_time(donor_inode);
+			ret2 = ext4_mark_inode_dirty(handle, donor_inode);
+			ext4_journal_stop(handle);
+		}
+
+		if (!ret1)
+			ret1 = ret2;
+	}
+
 	if (orig_path) {
 		ext4_ext_drop_refs(orig_path);
 		kfree(orig_path);