Re: [RFC PATCH v2 07/16] fs: split off need_file_update_time and do_file_update_time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 5/17/22 6:40 AM, Christian Brauner wrote:
> On Mon, May 16, 2022 at 09:47:09AM -0700, Stefan Roesch wrote:
>> This splits off the functions need_file_update_time() and
>> do_file_update_time() from the function file_update_time().
>>
>> This is required to support async buffered writes.
>> No intended functional changes in this patch.
>>
>> Signed-off-by: Stefan Roesch <shr@xxxxxx>
>> ---
>>  fs/inode.c | 71 ++++++++++++++++++++++++++++++++++++------------------
>>  1 file changed, 47 insertions(+), 24 deletions(-)
>>
>> diff --git a/fs/inode.c b/fs/inode.c
>> index a6d70a1983f8..1d0b02763e98 100644
>> --- a/fs/inode.c
>> +++ b/fs/inode.c
>> @@ -2054,35 +2054,22 @@ int file_remove_privs(struct file *file)
>>  }
>>  EXPORT_SYMBOL(file_remove_privs);
>>  
>> -/**
>> - *	file_update_time	-	update mtime and ctime time
>> - *	@file: file accessed
>> - *
>> - *	Update the mtime and ctime members of an inode and mark the inode
>> - *	for writeback.  Note that this function is meant exclusively for
>> - *	usage in the file write path of filesystems, and filesystems may
>> - *	choose to explicitly ignore update via this function with the
>> - *	S_NOCMTIME inode flag, e.g. for network filesystem where these
>> - *	timestamps are handled by the server.  This can return an error for
>> - *	file systems who need to allocate space in order to update an inode.
>> - */
>> -
>> -int file_update_time(struct file *file)
>> +static int need_file_update_time(struct inode *inode, struct file *file,
>> +				struct timespec64 *now)
> 
> I think file_need_update_time() is easier to understand.
> 

I renamed the function to file_needs_update_time().

>>  {
>> -	struct inode *inode = file_inode(file);
>> -	struct timespec64 now;
>>  	int sync_it = 0;
>> -	int ret;
>> +
>> +	if (unlikely(file->f_mode & FMODE_NOCMTIME))
>> +		return 0;
> 
> Moving this into this generic helper and using the generic helper
> directly in file_update_atime() leads to a change in behavior for
> file_update_time() callers. Currently they'd get time settings updated
> even if FMODE_NOCMTIME is set but with this change they'd not get it
> updated anymore if FMODE_NOCMTIME is set. Am I reading this right?
> 

Correct, this was not intended and will be addressed with the next version of the patch.

> Is this a bugfix? And if so it should be split into a separate commit...
> 
>>  
>>  	/* First try to exhaust all avenues to not sync */
>>  	if (IS_NOCMTIME(inode))
>>  		return 0;
>>  
>> -	now = current_time(inode);
>> -	if (!timespec64_equal(&inode->i_mtime, &now))
>> +	if (!timespec64_equal(&inode->i_mtime, now))
>>  		sync_it = S_MTIME;
>>  
>> -	if (!timespec64_equal(&inode->i_ctime, &now))
>> +	if (!timespec64_equal(&inode->i_ctime, now))
>>  		sync_it |= S_CTIME;
>>  
>>  	if (IS_I_VERSION(inode) && inode_iversion_need_inc(inode))
>> @@ -2091,15 +2078,49 @@ int file_update_time(struct file *file)
>>  	if (!sync_it)
>>  		return 0;
>>  
>> +	return sync_it;
>> +}
>> +
>> +static int do_file_update_time(struct inode *inode, struct file *file,
>> +			struct timespec64 *now, int sync_mode)
>> +{
>> +	int ret;
>> +
>>  	/* Finally allowed to write? Takes lock. */
>>  	if (__mnt_want_write_file(file))
>>  		return 0;
>>  
>> -	ret = inode_update_time(inode, &now, sync_it);
>> +	ret = inode_update_time(inode, now, sync_mode);
>>  	__mnt_drop_write_file(file);
>>  
>>  	return ret;
>>  }
> 
> Maybe
> 
> static int __file_update_time(struct inode *inode, struct file *file,
> 			      struct timespec64 *now, int sync_mode)
> {
> 	int ret = 0;
> 
> 	/* try to update time settings */
> 	if (!__mnt_want_write_file(file)) {
> 		ret = inode_update_time(inode, now, sync_mode);
> 		__mnt_drop_write_file(file);
> 	}
> 
> 	return ret;
> }
> 
> reads a little easier and the old comment is a bit confusing imho. I'd
> just say we keep it short. 
> 

I made the change.

>> +
>> +/**
>> + *	file_update_time	-	update mtime and ctime time
>> + *	@file: file accessed
>> + *
>> + *	Update the mtime and ctime members of an inode and mark the inode
>> + *	for writeback.  Note that this function is meant exclusively for
>> + *	usage in the file write path of filesystems, and filesystems may
>> + *	choose to explicitly ignore update via this function with the
>> + *	S_NOCMTIME inode flag, e.g. for network filesystem where these
>> + *	timestamps are handled by the server.  This can return an error for
>> + *	file systems who need to allocate space in order to update an inode.
>> + */
>> +
>> +int file_update_time(struct file *file)
> 
> My same lame complaint as before to make this kernel-doc. :)
> 
> /**
>  * file_update_time - update mtime and ctime time
>  * @file: file accessed
>  *
>  * Update the mtime and ctime members of an inode and mark the inode or
>  * writeback. Note that this function is meant exclusively for sage in
>  * the file write path of filesystems, and filesystems may hoose to
>  * explicitly ignore update via this function with the _NOCMTIME inode
>  * flag, e.g. for network filesystem where these imestamps are handled
>  * by the server. This can return an error for ile systems who need to
>  * allocate space in order to update an inode.
>  *
>  * Return: 0 on success, negative errno on failure.
>  */
> int file_update_time(struct file *file)
> 

I added the above kernel documentation, I only fixed a couple of typos.

>> +{
>> +	int err;
>> +	struct inode *inode = file_inode(file);
>> +	struct timespec64 now = current_time(inode);
>> +
>> +	err = need_file_update_time(inode, file, &now);
>> +	if (err < 0)
>> +		return err;
> 
> I may misread this but shouldn't this be err <= 0, i.e., if it returns 0
> then we don't need to update time?
> 

Good catch. Fixed.

>> +
>> +	return do_file_update_time(inode, file, &now, err);
>> +}
>>  EXPORT_SYMBOL(file_update_time);
>>  
>>  /* Caller must hold the file's inode lock */
>> @@ -2108,6 +2129,7 @@ int file_modified(struct file *file)
>>  	int ret;
>>  	struct dentry *dentry = file_dentry(file);
>>  	struct inode *inode = file_inode(file);
>> +	struct timespec64 now = current_time(inode);
>>  
>>  	/*
>>  	 * Clear the security bits if the process is not being run by root.
>> @@ -2122,10 +2144,11 @@ int file_modified(struct file *file)
>>  			return ret;
>>  	}
>>  
>> -	if (unlikely(file->f_mode & FMODE_NOCMTIME))
>> -		return 0;
>> +	ret = need_file_update_time(inode, file, &now);
>> +	if (ret <= 0)
>> +		return ret;
>>  
>> -	return file_update_time(file);
>> +	return do_file_update_time(inode, file, &now, ret);
>>  }
>>  EXPORT_SYMBOL(file_modified);
>>  
>> -- 
>> 2.30.2
>>



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux