Skip to content

Commit 1ed45a4

Browse files
committed
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>
2 parents 54ca9e9 + eff094a commit 1ed45a4

5 files changed

Lines changed: 29 additions & 49 deletions

File tree

fs/btrfs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6291,8 +6291,8 @@ static int btrfs_dirty_inode(struct btrfs_inode *inode)
62916291
}
62926292

62936293
/*
6294-
* This is a copy of file_update_time. We need this so we can return error on
6295-
* ENOSPC for updating the inode in the case of file write and mmap writes.
6294+
* We need our own ->update_time so that we can return error on ENOSPC for
6295+
* updating the inode in the case of file write and mmap writes.
62966296
*/
62976297
static int btrfs_update_time(struct inode *inode, int flags)
62986298
{

fs/btrfs/volumes.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,14 +2002,11 @@ static int btrfs_add_dev_item(struct btrfs_trans_handle *trans,
20022002
static void update_dev_time(const char *device_path)
20032003
{
20042004
struct path path;
2005-
int ret;
20062005

2007-
ret = kern_path(device_path, LOOKUP_FOLLOW, &path);
2008-
if (ret)
2009-
return;
2010-
2011-
inode_update_time(d_inode(path.dentry), S_MTIME | S_CTIME | S_VERSION);
2012-
path_put(&path);
2006+
if (!kern_path(device_path, LOOKUP_FOLLOW, &path)) {
2007+
vfs_utimes(&path, NULL);
2008+
path_put(&path);
2009+
}
20132010
}
20142011

20152012
static int btrfs_rm_dev_item(struct btrfs_trans_handle *trans,

fs/inode.c

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,42 +2310,40 @@ struct timespec64 current_time(struct inode *inode)
23102310
}
23112311
EXPORT_SYMBOL(current_time);
23122312

2313-
static int inode_needs_update_time(struct inode *inode)
2313+
static int file_update_time_flags(struct file *file, unsigned int flags)
23142314
{
2315+
struct inode *inode = file_inode(file);
23152316
struct timespec64 now, ts;
2316-
int sync_it = 0;
2317+
int sync_mode = 0;
2318+
int ret = 0;
23172319

23182320
/* First try to exhaust all avenues to not sync */
23192321
if (IS_NOCMTIME(inode))
23202322
return 0;
2323+
if (unlikely(file->f_mode & FMODE_NOCMTIME))
2324+
return 0;
23212325

23222326
now = current_time(inode);
23232327

23242328
ts = inode_get_mtime(inode);
23252329
if (!timespec64_equal(&ts, &now))
2326-
sync_it |= S_MTIME;
2327-
2330+
sync_mode |= S_MTIME;
23282331
ts = inode_get_ctime(inode);
23292332
if (!timespec64_equal(&ts, &now))
2330-
sync_it |= S_CTIME;
2331-
2333+
sync_mode |= S_CTIME;
23322334
if (IS_I_VERSION(inode) && inode_iversion_need_inc(inode))
2333-
sync_it |= S_VERSION;
2334-
2335-
return sync_it;
2336-
}
2335+
sync_mode |= S_VERSION;
23372336

2338-
static int __file_update_time(struct file *file, int sync_mode)
2339-
{
2340-
int ret = 0;
2341-
struct inode *inode = file_inode(file);
2337+
if (!sync_mode)
2338+
return 0;
23422339

2343-
/* try to update time settings */
2344-
if (!mnt_get_write_access_file(file)) {
2345-
ret = inode_update_time(inode, sync_mode);
2346-
mnt_put_write_access_file(file);
2347-
}
2340+
if (flags & IOCB_NOWAIT)
2341+
return -EAGAIN;
23482342

2343+
if (mnt_get_write_access_file(file))
2344+
return 0;
2345+
ret = inode_update_time(inode, sync_mode);
2346+
mnt_put_write_access_file(file);
23492347
return ret;
23502348
}
23512349

@@ -2365,14 +2363,7 @@ static int __file_update_time(struct file *file, int sync_mode)
23652363
*/
23662364
int file_update_time(struct file *file)
23672365
{
2368-
int ret;
2369-
struct inode *inode = file_inode(file);
2370-
2371-
ret = inode_needs_update_time(inode);
2372-
if (ret <= 0)
2373-
return ret;
2374-
2375-
return __file_update_time(file, ret);
2366+
return file_update_time_flags(file, 0);
23762367
}
23772368
EXPORT_SYMBOL(file_update_time);
23782369

@@ -2394,7 +2385,6 @@ EXPORT_SYMBOL(file_update_time);
23942385
static int file_modified_flags(struct file *file, int flags)
23952386
{
23962387
int ret;
2397-
struct inode *inode = file_inode(file);
23982388

23992389
/*
24002390
* 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)
24032393
ret = file_remove_privs_flags(file, flags);
24042394
if (ret)
24052395
return ret;
2406-
2407-
if (unlikely(file->f_mode & FMODE_NOCMTIME))
2408-
return 0;
2409-
2410-
ret = inode_needs_update_time(inode);
2411-
if (ret <= 0)
2412-
return ret;
2413-
if (flags & IOCB_NOWAIT)
2414-
return -EAGAIN;
2415-
2416-
return __file_update_time(file, ret);
2396+
return file_update_time_flags(file, flags);
24172397
}
24182398

24192399
/**

fs/orangefs/inode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,9 @@ int orangefs_update_time(struct inode *inode, int flags)
878878

879879
gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_update_time: %pU\n",
880880
get_khandle_from_ino(inode));
881-
flags = generic_update_time(inode, flags);
881+
882+
flags = inode_update_timestamps(inode, flags);
883+
882884
memset(&iattr, 0, sizeof iattr);
883885
if (flags & S_ATIME)
884886
iattr.ia_valid |= ATTR_ATIME;

fs/utimes.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ int vfs_utimes(const struct path *path, struct timespec64 *times)
7676
out:
7777
return error;
7878
}
79+
EXPORT_SYMBOL_GPL(vfs_utimes);
7980

8081
static int do_utimes_path(int dfd, const char __user *filename,
8182
struct timespec64 *times, int flags)

0 commit comments

Comments
 (0)