mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge patch series "re-enable IOCB_NOWAIT writes to files v2"
Christoph Hellwig <hch@lst.de> says: [Fix] the layering bypass in btrfs when updating timestamps on device files for devices removed from btrfs usage, and FMODE_NOCMTIME handling in the VFS now that nfsd started using it. Note that I'm still not sure that nfsd usage is fully correct for all file systems, as only XFS explicitly supports FMODE_NOCMTIME, but at least the generic code does the right thing now. * patches from https://patch.msgid.link/20251120064859.2911749-1-hch@lst.de: orangefs: use inode_update_timestamps directly btrfs: fix the comment on btrfs_update_time btrfs: use vfs_utimes to update file timestamps fs: export vfs_utimes fs: lift the FMODE_NOCMTIME check into file_update_time_flags fs: refactor file timestamp update logic Link: https://patch.msgid.link/20251120064859.2911749-1-hch@lst.de Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
@@ -6291,8 +6291,8 @@ static int btrfs_dirty_inode(struct btrfs_inode *inode)
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a copy of file_update_time. We need this so we can return error on
|
||||
* ENOSPC for updating the inode in the case of file write and mmap writes.
|
||||
* We need our own ->update_time so that we can return error on ENOSPC for
|
||||
* updating the inode in the case of file write and mmap writes.
|
||||
*/
|
||||
static int btrfs_update_time(struct inode *inode, int flags)
|
||||
{
|
||||
|
||||
@@ -2002,14 +2002,11 @@ out:
|
||||
static void update_dev_time(const char *device_path)
|
||||
{
|
||||
struct path path;
|
||||
int ret;
|
||||
|
||||
ret = kern_path(device_path, LOOKUP_FOLLOW, &path);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
inode_update_time(d_inode(path.dentry), S_MTIME | S_CTIME | S_VERSION);
|
||||
path_put(&path);
|
||||
if (!kern_path(device_path, LOOKUP_FOLLOW, &path)) {
|
||||
vfs_utimes(&path, NULL);
|
||||
path_put(&path);
|
||||
}
|
||||
}
|
||||
|
||||
static int btrfs_rm_dev_item(struct btrfs_trans_handle *trans,
|
||||
|
||||
58
fs/inode.c
58
fs/inode.c
@@ -2310,42 +2310,40 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(current_time);
|
||||
|
||||
static int inode_needs_update_time(struct inode *inode)
|
||||
static int file_update_time_flags(struct file *file, unsigned int flags)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct timespec64 now, ts;
|
||||
int sync_it = 0;
|
||||
int sync_mode = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* First try to exhaust all avenues to not sync */
|
||||
if (IS_NOCMTIME(inode))
|
||||
return 0;
|
||||
if (unlikely(file->f_mode & FMODE_NOCMTIME))
|
||||
return 0;
|
||||
|
||||
now = current_time(inode);
|
||||
|
||||
ts = inode_get_mtime(inode);
|
||||
if (!timespec64_equal(&ts, &now))
|
||||
sync_it |= S_MTIME;
|
||||
|
||||
sync_mode |= S_MTIME;
|
||||
ts = inode_get_ctime(inode);
|
||||
if (!timespec64_equal(&ts, &now))
|
||||
sync_it |= S_CTIME;
|
||||
|
||||
sync_mode |= S_CTIME;
|
||||
if (IS_I_VERSION(inode) && inode_iversion_need_inc(inode))
|
||||
sync_it |= S_VERSION;
|
||||
sync_mode |= S_VERSION;
|
||||
|
||||
return sync_it;
|
||||
}
|
||||
if (!sync_mode)
|
||||
return 0;
|
||||
|
||||
static int __file_update_time(struct file *file, int sync_mode)
|
||||
{
|
||||
int ret = 0;
|
||||
struct inode *inode = file_inode(file);
|
||||
|
||||
/* try to update time settings */
|
||||
if (!mnt_get_write_access_file(file)) {
|
||||
ret = inode_update_time(inode, sync_mode);
|
||||
mnt_put_write_access_file(file);
|
||||
}
|
||||
if (flags & IOCB_NOWAIT)
|
||||
return -EAGAIN;
|
||||
|
||||
if (mnt_get_write_access_file(file))
|
||||
return 0;
|
||||
ret = inode_update_time(inode, sync_mode);
|
||||
mnt_put_write_access_file(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2365,14 +2363,7 @@ static int __file_update_time(struct file *file, int sync_mode)
|
||||
*/
|
||||
int file_update_time(struct file *file)
|
||||
{
|
||||
int ret;
|
||||
struct inode *inode = file_inode(file);
|
||||
|
||||
ret = inode_needs_update_time(inode);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
return __file_update_time(file, ret);
|
||||
return file_update_time_flags(file, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(file_update_time);
|
||||
|
||||
@@ -2394,7 +2385,6 @@ EXPORT_SYMBOL(file_update_time);
|
||||
static int file_modified_flags(struct file *file, int flags)
|
||||
{
|
||||
int ret;
|
||||
struct inode *inode = file_inode(file);
|
||||
|
||||
/*
|
||||
* Clear the security bits if the process is not being run by root.
|
||||
@@ -2403,17 +2393,7 @@ static int file_modified_flags(struct file *file, int flags)
|
||||
ret = file_remove_privs_flags(file, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (unlikely(file->f_mode & FMODE_NOCMTIME))
|
||||
return 0;
|
||||
|
||||
ret = inode_needs_update_time(inode);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (flags & IOCB_NOWAIT)
|
||||
return -EAGAIN;
|
||||
|
||||
return __file_update_time(file, ret);
|
||||
return file_update_time_flags(file, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -878,7 +878,9 @@ int orangefs_update_time(struct inode *inode, int flags)
|
||||
|
||||
gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_update_time: %pU\n",
|
||||
get_khandle_from_ino(inode));
|
||||
flags = generic_update_time(inode, flags);
|
||||
|
||||
flags = inode_update_timestamps(inode, flags);
|
||||
|
||||
memset(&iattr, 0, sizeof iattr);
|
||||
if (flags & S_ATIME)
|
||||
iattr.ia_valid |= ATTR_ATIME;
|
||||
|
||||
@@ -76,6 +76,7 @@ retry_deleg:
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfs_utimes);
|
||||
|
||||
static int do_utimes_path(int dfd, const char __user *filename,
|
||||
struct timespec64 *times, int flags)
|
||||
|
||||
Reference in New Issue
Block a user