forked from Minki/linux
fs: Add async write file modification handling.
This adds a file_modified_async() function to return -EAGAIN if the request either requires to remove privileges or needs to update the file modification time. This is required for async buffered writes, so the request gets handled in the io worker of io-uring. Signed-off-by: Stefan Roesch <shr@fb.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20220623175157.1715274-11-shr@fb.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
6a2aa5d85d
commit
66fa3cedf1
79
fs/inode.c
79
fs/inode.c
@ -2115,6 +2115,47 @@ int file_update_time(struct file *file)
|
||||
}
|
||||
EXPORT_SYMBOL(file_update_time);
|
||||
|
||||
/**
|
||||
* file_modified_flags - handle mandated vfs changes when modifying a file
|
||||
* @file: file that was modified
|
||||
* @flags: kiocb flags
|
||||
*
|
||||
* When file has been modified ensure that special
|
||||
* file privileges are removed and time settings are updated.
|
||||
*
|
||||
* If IOCB_NOWAIT is set, special file privileges will not be removed and
|
||||
* time settings will not be updated. It will return -EAGAIN.
|
||||
*
|
||||
* Context: Caller must hold the file's inode lock.
|
||||
*
|
||||
* Return: 0 on success, negative errno on failure.
|
||||
*/
|
||||
static int file_modified_flags(struct file *file, int flags)
|
||||
{
|
||||
int ret;
|
||||
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.
|
||||
* This keeps people from modifying setuid and setgid binaries.
|
||||
*/
|
||||
ret = __file_remove_privs(file, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (unlikely(file->f_mode & FMODE_NOCMTIME))
|
||||
return 0;
|
||||
|
||||
ret = inode_needs_update_time(inode, &now);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (flags & IOCB_NOWAIT)
|
||||
return -EAGAIN;
|
||||
|
||||
return __file_update_time(file, &now, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* file_modified - handle mandated vfs changes when modifying a file
|
||||
* @file: file that was modified
|
||||
@ -2128,29 +2169,27 @@ EXPORT_SYMBOL(file_update_time);
|
||||
*/
|
||||
int file_modified(struct file *file)
|
||||
{
|
||||
int ret;
|
||||
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.
|
||||
* This keeps people from modifying setuid and setgid binaries.
|
||||
*/
|
||||
ret = __file_remove_privs(file, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (unlikely(file->f_mode & FMODE_NOCMTIME))
|
||||
return 0;
|
||||
|
||||
ret = inode_needs_update_time(inode, &now);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
return __file_update_time(file, &now, ret);
|
||||
return file_modified_flags(file, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(file_modified);
|
||||
|
||||
/**
|
||||
* kiocb_modified - handle mandated vfs changes when modifying a file
|
||||
* @iocb: iocb that was modified
|
||||
*
|
||||
* When file has been modified ensure that special
|
||||
* file privileges are removed and time settings are updated.
|
||||
*
|
||||
* Context: Caller must hold the file's inode lock.
|
||||
*
|
||||
* Return: 0 on success, negative errno on failure.
|
||||
*/
|
||||
int kiocb_modified(struct kiocb *iocb)
|
||||
{
|
||||
return file_modified_flags(iocb->ki_filp, iocb->ki_flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kiocb_modified);
|
||||
|
||||
int inode_needs_sync(struct inode *inode)
|
||||
{
|
||||
if (IS_SYNC(inode))
|
||||
|
@ -2390,6 +2390,7 @@ static inline void file_accessed(struct file *file)
|
||||
}
|
||||
|
||||
extern int file_modified(struct file *file);
|
||||
int kiocb_modified(struct kiocb *iocb);
|
||||
|
||||
int sync_inode_metadata(struct inode *inode, int wait);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user