Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-7.0-rc1.nonblocking_timestamps' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs timestamp updates from Christian Brauner:
"This contains the changes to support non-blocking timestamp updates.

Since commit 66fa3cedf16a ("fs: Add async write file modification
handling") file_update_time_flags() unconditionally returns -EAGAIN
when any timestamp needs updating and IOCB_NOWAIT is set. This makes
non-blocking direct writes impossible on file systems with granular
enough timestamps, which in practice means all of them.

This reworks the timestamp update path to propagate IOCB_NOWAIT
through ->update_time so that file systems which can update timestamps
without blocking are no longer penalized.

With that groundwork in place, the core change passes IOCB_NOWAIT into
->update_time and returns -EAGAIN only when the file system indicates
it would block.

XFS implements non-blocking timestamp updates by using the new
->sync_lazytime and open-coding generic_update_time without the
S_NOWAIT check, since the lazytime path through the generic helpers
can never block in XFS"

* tag 'vfs-7.0-rc1.nonblocking_timestamps' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
xfs: enable non-blocking timestamp updates
xfs: implement ->sync_lazytime
fs: refactor file_update_time_flags
fs: add support for non-blocking timestamp updates
fs: add a ->sync_lazytime method
fs: factor out a sync_lazytime helper
fs: refactor ->update_time handling
fat: cleanup the flags for fat_truncate_time
nfs: split nfs_update_timestamps
fs: allow error returns from generic_update_time
fs: remove inode_update_time

+331 -296
+4 -1
Documentation/filesystems/locking.rst
··· 80 80 int (*getattr) (struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); 81 81 ssize_t (*listxattr) (struct dentry *, char *, size_t); 82 82 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); 83 - void (*update_time)(struct inode *, struct timespec *, int); 83 + void (*update_time)(struct inode *inode, enum fs_update_time type, 84 + int flags); 85 + void (*sync_lazytime)(struct inode *inode); 84 86 int (*atomic_open)(struct inode *, struct dentry *, 85 87 struct file *, unsigned open_flag, 86 88 umode_t create_mode); ··· 119 117 listxattr: no 120 118 fiemap: no 121 119 update_time: no 120 + sync_lazytime: no 122 121 atomic_open: shared (exclusive if O_CREAT is set in open flags) 123 122 tmpfile: no 124 123 fileattr_get: no or exclusive
+8 -1
Documentation/filesystems/vfs.rst
··· 485 485 int (*setattr) (struct mnt_idmap *, struct dentry *, struct iattr *); 486 486 int (*getattr) (struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); 487 487 ssize_t (*listxattr) (struct dentry *, char *, size_t); 488 - void (*update_time)(struct inode *, struct timespec *, int); 488 + void (*update_time)(struct inode *inode, enum fs_update_time type, 489 + int flags); 490 + void (*sync_lazytime)(struct inode *inode); 489 491 int (*atomic_open)(struct inode *, struct dentry *, struct file *, 490 492 unsigned open_flag, umode_t create_mode); 491 493 int (*tmpfile) (struct mnt_idmap *, struct inode *, struct file *, umode_t); ··· 643 641 called by the VFS to update a specific time or the i_version of 644 642 an inode. If this is not defined the VFS will update the inode 645 643 itself and call mark_inode_dirty_sync. 644 + 645 + ``sync_lazytime``: 646 + called by the writeback code to update the lazy time stamps to 647 + regular time stamp updates that get syncing into the on-disk 648 + inode. 646 649 647 650 ``atomic_open`` 648 651 called on the last component of an open. Using this optional
+2 -1
fs/bad_inode.c
··· 133 133 return -EIO; 134 134 } 135 135 136 - static int bad_inode_update_time(struct inode *inode, int flags) 136 + static int bad_inode_update_time(struct inode *inode, enum fs_update_time type, 137 + unsigned int flags) 137 138 { 138 139 return -EIO; 139 140 }
+9 -4
fs/btrfs/inode.c
··· 6386 6386 * We need our own ->update_time so that we can return error on ENOSPC for 6387 6387 * updating the inode in the case of file write and mmap writes. 6388 6388 */ 6389 - static int btrfs_update_time(struct inode *inode, int flags) 6389 + static int btrfs_update_time(struct inode *inode, enum fs_update_time type, 6390 + unsigned int flags) 6390 6391 { 6391 6392 struct btrfs_root *root = BTRFS_I(inode)->root; 6392 - bool dirty; 6393 + int dirty; 6393 6394 6394 6395 if (btrfs_root_readonly(root)) 6395 6396 return -EROFS; 6397 + if (flags & IOCB_NOWAIT) 6398 + return -EAGAIN; 6396 6399 6397 - dirty = inode_update_timestamps(inode, flags); 6398 - return dirty ? btrfs_dirty_inode(BTRFS_I(inode)) : 0; 6400 + dirty = inode_update_time(inode, type, flags); 6401 + if (dirty <= 0) 6402 + return dirty; 6403 + return btrfs_dirty_inode(BTRFS_I(inode)); 6399 6404 } 6400 6405 6401 6406 /*
+1 -1
fs/fat/dir.c
··· 1080 1080 } 1081 1081 } 1082 1082 1083 - fat_truncate_time(dir, NULL, S_ATIME|S_MTIME); 1083 + fat_truncate_time(dir, NULL, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); 1084 1084 if (IS_DIRSYNC(dir)) 1085 1085 (void)fat_sync_inode(dir); 1086 1086 else
+6 -5
fs/fat/fat.h
··· 468 468 __le16 *time, __le16 *date, u8 *time_cs); 469 469 extern struct timespec64 fat_truncate_atime(const struct msdos_sb_info *sbi, 470 470 const struct timespec64 *ts); 471 - extern struct timespec64 fat_truncate_mtime(const struct msdos_sb_info *sbi, 472 - const struct timespec64 *ts); 473 - extern int fat_truncate_time(struct inode *inode, struct timespec64 *now, 474 - int flags); 475 - extern int fat_update_time(struct inode *inode, int flags); 471 + #define FAT_UPDATE_ATIME (1u << 0) 472 + #define FAT_UPDATE_CMTIME (1u << 1) 473 + void fat_truncate_time(struct inode *inode, struct timespec64 *now, 474 + unsigned int flags); 475 + int fat_update_time(struct inode *inode, enum fs_update_time type, 476 + unsigned int flags); 476 477 extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); 477 478 478 479 int fat_cache_init(void);
+6 -8
fs/fat/file.c
··· 224 224 if (err) 225 225 goto out; 226 226 227 - fat_truncate_time(inode, NULL, S_CTIME|S_MTIME); 227 + fat_truncate_time(inode, NULL, FAT_UPDATE_CMTIME); 228 228 mark_inode_dirty(inode); 229 229 if (IS_SYNC(inode)) { 230 230 int err2; ··· 327 327 MSDOS_I(inode)->i_logstart = 0; 328 328 } 329 329 MSDOS_I(inode)->i_attrs |= ATTR_ARCH; 330 - fat_truncate_time(inode, NULL, S_CTIME|S_MTIME); 330 + fat_truncate_time(inode, NULL, FAT_UPDATE_CMTIME); 331 331 if (wait) { 332 332 err = fat_sync_inode(inode); 333 333 if (err) { ··· 553 553 } 554 554 555 555 /* 556 - * setattr_copy can't truncate these appropriately, so we'll 557 - * copy them ourselves 556 + * setattr_copy can't truncate these appropriately, so we'll copy them 557 + * ourselves. See fat_truncate_time for the c/mtime logic on fat. 558 558 */ 559 559 if (attr->ia_valid & ATTR_ATIME) 560 - fat_truncate_time(inode, &attr->ia_atime, S_ATIME); 561 - if (attr->ia_valid & ATTR_CTIME) 562 - fat_truncate_time(inode, &attr->ia_ctime, S_CTIME); 560 + fat_truncate_time(inode, &attr->ia_atime, FAT_UPDATE_ATIME); 563 561 if (attr->ia_valid & ATTR_MTIME) 564 - fat_truncate_time(inode, &attr->ia_mtime, S_MTIME); 562 + fat_truncate_time(inode, &attr->ia_mtime, FAT_UPDATE_CMTIME); 565 563 attr->ia_valid &= ~(ATTR_ATIME|ATTR_CTIME|ATTR_MTIME); 566 564 567 565 setattr_copy(idmap, inode, attr);
+1 -1
fs/fat/inode.c
··· 246 246 if (err < len) 247 247 fat_write_failed(mapping, pos + len); 248 248 if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { 249 - fat_truncate_time(inode, NULL, S_CTIME|S_MTIME); 249 + fat_truncate_time(inode, NULL, FAT_UPDATE_CMTIME); 250 250 MSDOS_I(inode)->i_attrs |= ATTR_ARCH; 251 251 mark_inode_dirty(inode); 252 252 }
+22 -37
fs/fat/misc.c
··· 299 299 } 300 300 301 301 /* 302 - * truncate mtime to 2 second granularity 302 + * Update the in-inode atime and/or mtime after truncating the timestamp to the 303 + * granularity. All timestamps in root inode are always 0. 304 + * 305 + * ctime and mtime share the same on-disk field, and should be identical in 306 + * memory. All mtime updates will be applied to ctime, but ctime updates are 307 + * ignored. 303 308 */ 304 - struct timespec64 fat_truncate_mtime(const struct msdos_sb_info *sbi, 305 - const struct timespec64 *ts) 306 - { 307 - return fat_timespec64_trunc_2secs(*ts); 308 - } 309 - 310 - /* 311 - * truncate the various times with appropriate granularity: 312 - * all times in root node are always 0 313 - */ 314 - int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags) 309 + void fat_truncate_time(struct inode *inode, struct timespec64 *now, 310 + unsigned int flags) 315 311 { 316 312 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 317 313 struct timespec64 ts; 318 314 319 315 if (inode->i_ino == MSDOS_ROOT_INO) 320 - return 0; 316 + return; 321 317 322 318 if (now == NULL) { 323 319 now = &ts; 324 320 ts = current_time(inode); 325 321 } 326 322 327 - if (flags & S_ATIME) 323 + if (flags & FAT_UPDATE_ATIME) 328 324 inode_set_atime_to_ts(inode, fat_truncate_atime(sbi, now)); 329 - /* 330 - * ctime and mtime share the same on-disk field, and should be 331 - * identical in memory. all mtime updates will be applied to ctime, 332 - * but ctime updates are ignored. 333 - */ 334 - if (flags & S_MTIME) 335 - inode_set_mtime_to_ts(inode, 336 - inode_set_ctime_to_ts(inode, fat_truncate_mtime(sbi, now))); 325 + if (flags & FAT_UPDATE_CMTIME) { 326 + /* truncate mtime to 2 second granularity */ 327 + struct timespec64 mtime = fat_timespec64_trunc_2secs(*now); 337 328 338 - return 0; 329 + inode_set_mtime_to_ts(inode, mtime); 330 + inode_set_ctime_to_ts(inode, mtime); 331 + } 339 332 } 340 333 EXPORT_SYMBOL_GPL(fat_truncate_time); 341 334 342 - int fat_update_time(struct inode *inode, int flags) 335 + int fat_update_time(struct inode *inode, enum fs_update_time type, 336 + unsigned int flags) 343 337 { 344 - int dirty_flags = 0; 345 - 346 - if (inode->i_ino == MSDOS_ROOT_INO) 347 - return 0; 348 - 349 - if (flags & (S_ATIME | S_CTIME | S_MTIME)) { 350 - fat_truncate_time(inode, NULL, flags); 351 - if (inode->i_sb->s_flags & SB_LAZYTIME) 352 - dirty_flags |= I_DIRTY_TIME; 353 - else 354 - dirty_flags |= I_DIRTY_SYNC; 338 + if (inode->i_ino != MSDOS_ROOT_INO) { 339 + fat_truncate_time(inode, NULL, type == FS_UPD_ATIME ? 340 + FAT_UPDATE_ATIME : FAT_UPDATE_CMTIME); 341 + __mark_inode_dirty(inode, inode_time_dirty_flag(inode)); 355 342 } 356 - 357 - __mark_inode_dirty(inode, dirty_flags); 358 343 return 0; 359 344 } 360 345 EXPORT_SYMBOL_GPL(fat_update_time);
+5 -8
fs/fat/namei_msdos.c
··· 251 251 if (err) 252 252 return err; 253 253 254 - fat_truncate_time(dir, ts, S_CTIME|S_MTIME); 254 + fat_truncate_time(dir, ts, FAT_UPDATE_CMTIME); 255 255 if (IS_DIRSYNC(dir)) 256 256 (void)fat_sync_inode(dir); 257 257 else ··· 295 295 err = PTR_ERR(inode); 296 296 goto out; 297 297 } 298 - fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); 298 + fat_truncate_time(inode, &ts, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); 299 299 /* timestamp is already written, so mark_inode_dirty() is unneeded. */ 300 300 301 301 d_instantiate(dentry, inode); ··· 328 328 drop_nlink(dir); 329 329 330 330 clear_nlink(inode); 331 - fat_truncate_time(inode, NULL, S_CTIME); 332 331 fat_detach(inode); 333 332 out: 334 333 mutex_unlock(&MSDOS_SB(sb)->s_lock); ··· 381 382 goto out; 382 383 } 383 384 set_nlink(inode, 2); 384 - fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); 385 + fat_truncate_time(inode, &ts, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); 385 386 /* timestamp is already written, so mark_inode_dirty() is unneeded. */ 386 387 387 388 d_instantiate(dentry, inode); ··· 414 415 if (err) 415 416 goto out; 416 417 clear_nlink(inode); 417 - fat_truncate_time(inode, NULL, S_CTIME); 418 418 fat_detach(inode); 419 419 out: 420 420 mutex_unlock(&MSDOS_SB(sb)->s_lock); ··· 478 480 mark_inode_dirty(old_inode); 479 481 480 482 inode_inc_iversion(old_dir); 481 - fat_truncate_time(old_dir, NULL, S_CTIME|S_MTIME); 483 + fat_truncate_time(old_dir, NULL, FAT_UPDATE_CMTIME); 482 484 if (IS_DIRSYNC(old_dir)) 483 485 (void)fat_sync_inode(old_dir); 484 486 else ··· 538 540 if (err) 539 541 goto error_dotdot; 540 542 inode_inc_iversion(old_dir); 541 - fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME); 543 + fat_truncate_time(old_dir, &ts, FAT_UPDATE_CMTIME); 542 544 if (IS_DIRSYNC(old_dir)) 543 545 (void)fat_sync_inode(old_dir); 544 546 else ··· 548 550 drop_nlink(new_inode); 549 551 if (is_dir) 550 552 drop_nlink(new_inode); 551 - fat_truncate_time(new_inode, &ts, S_CTIME); 552 553 } 553 554 out: 554 555 brelse(sinfo.bh);
+4 -5
fs/fat/namei_vfat.c
··· 676 676 goto cleanup; 677 677 678 678 /* update timestamp */ 679 - fat_truncate_time(dir, ts, S_CTIME|S_MTIME); 679 + fat_truncate_time(dir, ts, FAT_UPDATE_CMTIME); 680 680 if (IS_DIRSYNC(dir)) 681 681 (void)fat_sync_inode(dir); 682 682 else ··· 806 806 drop_nlink(dir); 807 807 808 808 clear_nlink(inode); 809 - fat_truncate_time(inode, NULL, S_ATIME|S_MTIME); 809 + fat_truncate_time(inode, NULL, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); 810 810 fat_detach(inode); 811 811 vfat_d_version_set(dentry, inode_query_iversion(dir)); 812 812 out: ··· 832 832 if (err) 833 833 goto out; 834 834 clear_nlink(inode); 835 - fat_truncate_time(inode, NULL, S_ATIME|S_MTIME); 835 + fat_truncate_time(inode, NULL, FAT_UPDATE_ATIME | FAT_UPDATE_CMTIME); 836 836 fat_detach(inode); 837 837 vfat_d_version_set(dentry, inode_query_iversion(dir)); 838 838 out: ··· 918 918 static void vfat_update_dir_metadata(struct inode *dir, struct timespec64 *ts) 919 919 { 920 920 inode_inc_iversion(dir); 921 - fat_truncate_time(dir, ts, S_CTIME | S_MTIME); 921 + fat_truncate_time(dir, ts, FAT_UPDATE_CMTIME); 922 922 if (IS_DIRSYNC(dir)) 923 923 (void)fat_sync_inode(dir); 924 924 else ··· 996 996 drop_nlink(new_inode); 997 997 if (is_dir) 998 998 drop_nlink(new_inode); 999 - fat_truncate_time(new_inode, &ts, S_CTIME); 1000 999 } 1001 1000 out: 1002 1001 brelse(sinfo.bh);
+25 -8
fs/fs-writeback.c
··· 1711 1711 } 1712 1712 } 1713 1713 1714 + bool sync_lazytime(struct inode *inode) 1715 + { 1716 + if (!(inode_state_read_once(inode) & I_DIRTY_TIME)) 1717 + return false; 1718 + 1719 + trace_writeback_lazytime(inode); 1720 + if (inode->i_op->sync_lazytime) 1721 + inode->i_op->sync_lazytime(inode); 1722 + else 1723 + mark_inode_dirty_sync(inode); 1724 + return true; 1725 + } 1726 + 1714 1727 /* 1715 1728 * Write out an inode and its dirty pages (or some of its dirty pages, depending 1716 1729 * on @wbc->nr_to_write), and clear the relevant dirty flags from i_state. ··· 1763 1750 } 1764 1751 1765 1752 /* 1766 - * If the inode has dirty timestamps and we need to write them, call 1767 - * mark_inode_dirty_sync() to notify the filesystem about it and to 1768 - * change I_DIRTY_TIME into I_DIRTY_SYNC. 1753 + * For data integrity writeback, or when the dirty interval expired, 1754 + * ask the file system to propagata lazy timestamp updates into real 1755 + * dirty state. 1769 1756 */ 1770 1757 if ((inode_state_read_once(inode) & I_DIRTY_TIME) && 1771 1758 (wbc->sync_mode == WB_SYNC_ALL || 1772 1759 time_after(jiffies, inode->dirtied_time_when + 1773 - dirtytime_expire_interval * HZ))) { 1774 - trace_writeback_lazytime(inode); 1775 - mark_inode_dirty_sync(inode); 1776 - } 1760 + dirtytime_expire_interval * HZ))) 1761 + sync_lazytime(inode); 1777 1762 1778 1763 /* 1779 1764 * Get and clear the dirty flags from i_state. This needs to be done ··· 2580 2569 trace_writeback_mark_inode_dirty(inode, flags); 2581 2570 2582 2571 if (flags & I_DIRTY_INODE) { 2572 + bool was_dirty_time = false; 2573 + 2583 2574 /* 2584 2575 * Inode timestamp update will piggback on this dirtying. 2585 2576 * We tell ->dirty_inode callback that timestamps need to ··· 2592 2579 if (inode_state_read(inode) & I_DIRTY_TIME) { 2593 2580 inode_state_clear(inode, I_DIRTY_TIME); 2594 2581 flags |= I_DIRTY_TIME; 2582 + was_dirty_time = true; 2595 2583 } 2596 2584 spin_unlock(&inode->i_lock); 2597 2585 } ··· 2605 2591 * for just I_DIRTY_PAGES or I_DIRTY_TIME. 2606 2592 */ 2607 2593 trace_writeback_dirty_inode_start(inode, flags); 2608 - if (sb->s_op->dirty_inode) 2594 + if (sb->s_op->dirty_inode) { 2609 2595 sb->s_op->dirty_inode(inode, 2610 2596 flags & (I_DIRTY_INODE | I_DIRTY_TIME)); 2597 + } else if (was_dirty_time && inode->i_op->sync_lazytime) { 2598 + inode->i_op->sync_lazytime(inode); 2599 + } 2611 2600 trace_writeback_dirty_inode(inode, flags); 2612 2601 2613 2602 /* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
+6 -3
fs/gfs2/inode.c
··· 2242 2242 return vfs_setpos(file, ret, inode->i_sb->s_maxbytes); 2243 2243 } 2244 2244 2245 - static int gfs2_update_time(struct inode *inode, int flags) 2245 + static int gfs2_update_time(struct inode *inode, enum fs_update_time type, 2246 + unsigned int flags) 2246 2247 { 2247 2248 struct gfs2_inode *ip = GFS2_I(inode); 2248 2249 struct gfs2_glock *gl = ip->i_gl; 2249 2250 struct gfs2_holder *gh; 2250 2251 int error; 2252 + 2253 + if (flags & IOCB_NOWAIT) 2254 + return -EAGAIN; 2251 2255 2252 2256 gh = gfs2_glock_is_locked_by_me(gl); 2253 2257 if (gh && gl->gl_state != LM_ST_EXCLUSIVE) { ··· 2261 2257 if (error) 2262 2258 return error; 2263 2259 } 2264 - generic_update_time(inode, flags); 2265 - return 0; 2260 + return generic_update_time(inode, type, flags); 2266 2261 } 2267 2262 2268 2263 static const struct inode_operations gfs2_file_iops = {
+116 -98
fs/inode.c
··· 1982 1982 if (atomic_add_unless(&inode->i_count, -1, 1)) 1983 1983 return; 1984 1984 1985 - if ((inode_state_read_once(inode) & I_DIRTY_TIME) && inode->i_nlink) { 1986 - trace_writeback_lazytime_iput(inode); 1987 - mark_inode_dirty_sync(inode); 1985 + if (inode->i_nlink && sync_lazytime(inode)) 1988 1986 goto retry; 1989 - } 1990 1987 1991 1988 spin_lock(&inode->i_lock); 1992 1989 if (unlikely((inode_state_read(inode) & I_DIRTY_TIME) && inode->i_nlink)) { ··· 2081 2084 return false; 2082 2085 } 2083 2086 2084 - /** 2085 - * inode_update_timestamps - update the timestamps on the inode 2086 - * @inode: inode to be updated 2087 - * @flags: S_* flags that needed to be updated 2088 - * 2089 - * The update_time function is called when an inode's timestamps need to be 2090 - * updated for a read or write operation. This function handles updating the 2091 - * actual timestamps. It's up to the caller to ensure that the inode is marked 2092 - * dirty appropriately. 2093 - * 2094 - * In the case where any of S_MTIME, S_CTIME, or S_VERSION need to be updated, 2095 - * attempt to update all three of them. S_ATIME updates can be handled 2096 - * independently of the rest. 2097 - * 2098 - * Returns a set of S_* flags indicating which values changed. 2099 - */ 2100 - int inode_update_timestamps(struct inode *inode, int flags) 2087 + static int inode_update_atime(struct inode *inode) 2101 2088 { 2102 - int updated = 0; 2103 - struct timespec64 now; 2089 + struct timespec64 atime = inode_get_atime(inode); 2090 + struct timespec64 now = current_time(inode); 2104 2091 2105 - if (flags & (S_MTIME|S_CTIME|S_VERSION)) { 2106 - struct timespec64 ctime = inode_get_ctime(inode); 2107 - struct timespec64 mtime = inode_get_mtime(inode); 2092 + if (timespec64_equal(&now, &atime)) 2093 + return 0; 2108 2094 2109 - now = inode_set_ctime_current(inode); 2110 - if (!timespec64_equal(&now, &ctime)) 2111 - updated |= S_CTIME; 2112 - if (!timespec64_equal(&now, &mtime)) { 2113 - inode_set_mtime_to_ts(inode, now); 2114 - updated |= S_MTIME; 2115 - } 2116 - if (IS_I_VERSION(inode) && inode_maybe_inc_iversion(inode, updated)) 2117 - updated |= S_VERSION; 2118 - } else { 2119 - now = current_time(inode); 2120 - } 2121 - 2122 - if (flags & S_ATIME) { 2123 - struct timespec64 atime = inode_get_atime(inode); 2124 - 2125 - if (!timespec64_equal(&now, &atime)) { 2126 - inode_set_atime_to_ts(inode, now); 2127 - updated |= S_ATIME; 2128 - } 2129 - } 2130 - return updated; 2095 + inode_set_atime_to_ts(inode, now); 2096 + return inode_time_dirty_flag(inode); 2131 2097 } 2132 - EXPORT_SYMBOL(inode_update_timestamps); 2098 + 2099 + static int inode_update_cmtime(struct inode *inode, unsigned int flags) 2100 + { 2101 + struct timespec64 ctime = inode_get_ctime(inode); 2102 + struct timespec64 mtime = inode_get_mtime(inode); 2103 + struct timespec64 now = inode_set_ctime_current(inode); 2104 + unsigned int dirty = 0; 2105 + bool mtime_changed; 2106 + 2107 + mtime_changed = !timespec64_equal(&now, &mtime); 2108 + if (mtime_changed || !timespec64_equal(&now, &ctime)) 2109 + dirty = inode_time_dirty_flag(inode); 2110 + 2111 + /* 2112 + * Pure timestamp updates can be recorded in the inode without blocking 2113 + * by not dirtying the inode. But when the file system requires 2114 + * i_version updates, the update of i_version can still block. 2115 + * Error out if we'd actually have to update i_version or don't support 2116 + * lazytime. 2117 + */ 2118 + if (IS_I_VERSION(inode)) { 2119 + if (flags & IOCB_NOWAIT) { 2120 + if (!(inode->i_sb->s_flags & SB_LAZYTIME) || 2121 + inode_iversion_need_inc(inode)) 2122 + return -EAGAIN; 2123 + } else { 2124 + if (inode_maybe_inc_iversion(inode, !!dirty)) 2125 + dirty |= I_DIRTY_SYNC; 2126 + } 2127 + } 2128 + 2129 + if (mtime_changed) 2130 + inode_set_mtime_to_ts(inode, now); 2131 + return dirty; 2132 + } 2133 + 2134 + /** 2135 + * inode_update_time - update either atime or c/mtime and i_version on the inode 2136 + * @inode: inode to be updated 2137 + * @type: timestamp to be updated 2138 + * @flags: flags for the update 2139 + * 2140 + * Update either atime or c/mtime and version in a inode if needed for a file 2141 + * access or modification. It is up to the caller to mark the inode dirty 2142 + * appropriately. 2143 + * 2144 + * Returns the positive I_DIRTY_* flags for __mark_inode_dirty() if the inode 2145 + * needs to be marked dirty, 0 if it did not, or a negative errno if an error 2146 + * happened. 2147 + */ 2148 + int inode_update_time(struct inode *inode, enum fs_update_time type, 2149 + unsigned int flags) 2150 + { 2151 + switch (type) { 2152 + case FS_UPD_ATIME: 2153 + return inode_update_atime(inode); 2154 + case FS_UPD_CMTIME: 2155 + return inode_update_cmtime(inode, flags); 2156 + default: 2157 + WARN_ON_ONCE(1); 2158 + return -EIO; 2159 + } 2160 + } 2161 + EXPORT_SYMBOL(inode_update_time); 2133 2162 2134 2163 /** 2135 2164 * generic_update_time - update the timestamps on the inode 2136 2165 * @inode: inode to be updated 2137 - * @flags: S_* flags that needed to be updated 2166 + * @type: timestamp to be updated 2167 + * @flags: flags for the update 2138 2168 * 2139 - * The update_time function is called when an inode's timestamps need to be 2140 - * updated for a read or write operation. In the case where any of S_MTIME, S_CTIME, 2141 - * or S_VERSION need to be updated we attempt to update all three of them. S_ATIME 2142 - * updates can be handled done independently of the rest. 2143 - * 2144 - * Returns a S_* mask indicating which fields were updated. 2169 + * Returns a negative error value on error, else 0. 2145 2170 */ 2146 - int generic_update_time(struct inode *inode, int flags) 2171 + int generic_update_time(struct inode *inode, enum fs_update_time type, 2172 + unsigned int flags) 2147 2173 { 2148 - int updated = inode_update_timestamps(inode, flags); 2149 - int dirty_flags = 0; 2174 + int dirty; 2150 2175 2151 - if (updated & (S_ATIME|S_MTIME|S_CTIME)) 2152 - dirty_flags = inode->i_sb->s_flags & SB_LAZYTIME ? I_DIRTY_TIME : I_DIRTY_SYNC; 2153 - if (updated & S_VERSION) 2154 - dirty_flags |= I_DIRTY_SYNC; 2155 - __mark_inode_dirty(inode, dirty_flags); 2156 - return updated; 2157 - } 2158 - EXPORT_SYMBOL(generic_update_time); 2176 + /* 2177 + * ->dirty_inode is what could make generic timestamp updates block. 2178 + * Don't support non-blocking timestamp updates here if it is set. 2179 + * File systems that implement ->dirty_inode but want to support 2180 + * non-blocking timestamp updates should call inode_update_time 2181 + * directly. 2182 + */ 2183 + if ((flags & IOCB_NOWAIT) && inode->i_sb->s_op->dirty_inode) 2184 + return -EAGAIN; 2159 2185 2160 - /* 2161 - * This does the actual work of updating an inodes time or version. Must have 2162 - * had called mnt_want_write() before calling this. 2163 - */ 2164 - int inode_update_time(struct inode *inode, int flags) 2165 - { 2166 - if (inode->i_op->update_time) 2167 - return inode->i_op->update_time(inode, flags); 2168 - generic_update_time(inode, flags); 2186 + dirty = inode_update_time(inode, type, flags); 2187 + if (dirty <= 0) 2188 + return dirty; 2189 + __mark_inode_dirty(inode, dirty); 2169 2190 return 0; 2170 2191 } 2171 - EXPORT_SYMBOL(inode_update_time); 2192 + EXPORT_SYMBOL(generic_update_time); 2172 2193 2173 2194 /** 2174 2195 * atime_needs_update - update the access time ··· 2255 2240 * We may also fail on filesystems that have the ability to make parts 2256 2241 * of the fs read only, e.g. subvolumes in Btrfs. 2257 2242 */ 2258 - inode_update_time(inode, S_ATIME); 2243 + if (inode->i_op->update_time) 2244 + inode->i_op->update_time(inode, FS_UPD_ATIME, 0); 2245 + else 2246 + generic_update_time(inode, FS_UPD_ATIME, 0); 2259 2247 mnt_put_write_access(mnt); 2260 2248 skip_update: 2261 2249 sb_end_write(inode->i_sb); ··· 2381 2363 } 2382 2364 EXPORT_SYMBOL(current_time); 2383 2365 2366 + static inline bool need_cmtime_update(struct inode *inode) 2367 + { 2368 + struct timespec64 now = current_time(inode), ts; 2369 + 2370 + ts = inode_get_mtime(inode); 2371 + if (!timespec64_equal(&ts, &now)) 2372 + return true; 2373 + ts = inode_get_ctime(inode); 2374 + if (!timespec64_equal(&ts, &now)) 2375 + return true; 2376 + return IS_I_VERSION(inode) && inode_iversion_need_inc(inode); 2377 + } 2378 + 2384 2379 static int file_update_time_flags(struct file *file, unsigned int flags) 2385 2380 { 2386 2381 struct inode *inode = file_inode(file); 2387 - struct timespec64 now, ts; 2388 - int sync_mode = 0; 2389 - int ret = 0; 2382 + int ret; 2390 2383 2391 2384 /* First try to exhaust all avenues to not sync */ 2392 2385 if (IS_NOCMTIME(inode)) 2393 2386 return 0; 2394 2387 if (unlikely(file->f_mode & FMODE_NOCMTIME)) 2395 2388 return 0; 2396 - 2397 - now = current_time(inode); 2398 - 2399 - ts = inode_get_mtime(inode); 2400 - if (!timespec64_equal(&ts, &now)) 2401 - sync_mode |= S_MTIME; 2402 - ts = inode_get_ctime(inode); 2403 - if (!timespec64_equal(&ts, &now)) 2404 - sync_mode |= S_CTIME; 2405 - if (IS_I_VERSION(inode) && inode_iversion_need_inc(inode)) 2406 - sync_mode |= S_VERSION; 2407 - 2408 - if (!sync_mode) 2389 + if (!need_cmtime_update(inode)) 2409 2390 return 0; 2410 2391 2411 - if (flags & IOCB_NOWAIT) 2412 - return -EAGAIN; 2413 - 2392 + flags &= IOCB_NOWAIT; 2414 2393 if (mnt_get_write_access_file(file)) 2415 2394 return 0; 2416 - ret = inode_update_time(inode, sync_mode); 2395 + if (inode->i_op->update_time) 2396 + ret = inode->i_op->update_time(inode, FS_UPD_CMTIME, flags); 2397 + else 2398 + ret = generic_update_time(inode, FS_UPD_CMTIME, flags); 2417 2399 mnt_put_write_access_file(file); 2418 2400 return ret; 2419 2401 }
+2 -1
fs/internal.h
··· 214 214 /* 215 215 * fs-writeback.c 216 216 */ 217 - extern long get_nr_dirty_inodes(void); 217 + long get_nr_dirty_inodes(void); 218 + bool sync_lazytime(struct inode *inode); 218 219 219 220 /* 220 221 * dcache.c
+18 -19
fs/nfs/inode.c
··· 649 649 struct timespec64 ctime = inode_get_ctime(inode); 650 650 struct timespec64 mtime = inode_get_mtime(inode); 651 651 struct timespec64 now; 652 - int updated = 0; 652 + bool updated = false; 653 653 654 654 now = inode_set_ctime_current(inode); 655 655 if (!timespec64_equal(&now, &ctime)) 656 - updated |= S_CTIME; 656 + updated = true; 657 657 658 658 inode_set_mtime_to_ts(inode, attr->ia_mtime); 659 659 if (!timespec64_equal(&now, &mtime)) 660 - updated |= S_MTIME; 660 + updated = true; 661 661 662 662 inode_maybe_inc_iversion(inode, updated); 663 663 cache_flags |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; ··· 669 669 NFS_I(inode)->cache_validity &= ~cache_flags; 670 670 } 671 671 672 - static void nfs_update_timestamps(struct inode *inode, unsigned int ia_valid) 672 + static void nfs_update_atime(struct inode *inode) 673 673 { 674 - enum file_time_flags time_flags = 0; 675 - unsigned int cache_flags = 0; 674 + inode_update_time(inode, FS_UPD_ATIME, 0); 675 + NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ATIME; 676 + } 676 677 677 - if (ia_valid & ATTR_MTIME) { 678 - time_flags |= S_MTIME | S_CTIME; 679 - cache_flags |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; 680 - } 681 - if (ia_valid & ATTR_ATIME) { 682 - time_flags |= S_ATIME; 683 - cache_flags |= NFS_INO_INVALID_ATIME; 684 - } 685 - inode_update_timestamps(inode, time_flags); 686 - NFS_I(inode)->cache_validity &= ~cache_flags; 678 + static void nfs_update_mtime(struct inode *inode) 679 + { 680 + inode_update_time(inode, FS_UPD_CMTIME, 0); 681 + NFS_I(inode)->cache_validity &= 682 + ~(NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME); 687 683 } 688 684 689 685 void nfs_update_delegated_atime(struct inode *inode) 690 686 { 691 687 spin_lock(&inode->i_lock); 692 688 if (nfs_have_delegated_atime(inode)) 693 - nfs_update_timestamps(inode, ATTR_ATIME); 689 + nfs_update_atime(inode); 694 690 spin_unlock(&inode->i_lock); 695 691 } 696 692 697 693 void nfs_update_delegated_mtime_locked(struct inode *inode) 698 694 { 699 695 if (nfs_have_delegated_mtime(inode)) 700 - nfs_update_timestamps(inode, ATTR_MTIME); 696 + nfs_update_mtime(inode); 701 697 } 702 698 703 699 void nfs_update_delegated_mtime(struct inode *inode) ··· 747 751 ATTR_ATIME|ATTR_ATIME_SET); 748 752 } 749 753 } else { 750 - nfs_update_timestamps(inode, attr->ia_valid); 754 + if (attr->ia_valid & ATTR_MTIME) 755 + nfs_update_mtime(inode); 756 + if (attr->ia_valid & ATTR_ATIME) 757 + nfs_update_atime(inode); 751 758 attr->ia_valid &= ~(ATTR_MTIME|ATTR_ATIME); 752 759 } 753 760 spin_unlock(&inode->i_lock);
+17 -12
fs/orangefs/inode.c
··· 872 872 return generic_permission(&nop_mnt_idmap, inode, mask); 873 873 } 874 874 875 - int orangefs_update_time(struct inode *inode, int flags) 875 + int orangefs_update_time(struct inode *inode, enum fs_update_time type, 876 + unsigned int flags) 876 877 { 877 - struct iattr iattr; 878 + struct iattr iattr = { }; 879 + int dirty; 878 880 879 - gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_update_time: %pU\n", 880 - get_khandle_from_ino(inode)); 881 + if (flags & IOCB_NOWAIT) 882 + return -EAGAIN; 881 883 882 - flags = inode_update_timestamps(inode, flags); 884 + switch (type) { 885 + case FS_UPD_ATIME: 886 + iattr.ia_valid = ATTR_ATIME; 887 + break; 888 + case FS_UPD_CMTIME: 889 + iattr.ia_valid = ATTR_CTIME | ATTR_MTIME; 890 + break; 891 + } 883 892 884 - memset(&iattr, 0, sizeof iattr); 885 - if (flags & S_ATIME) 886 - iattr.ia_valid |= ATTR_ATIME; 887 - if (flags & S_CTIME) 888 - iattr.ia_valid |= ATTR_CTIME; 889 - if (flags & S_MTIME) 890 - iattr.ia_valid |= ATTR_MTIME; 893 + dirty = inode_update_time(inode, type, flags); 894 + if (dirty <= 0) 895 + return dirty; 891 896 return __orangefs_setattr(inode, &iattr); 892 897 } 893 898
+2 -1
fs/orangefs/orangefs-kernel.h
··· 360 360 int orangefs_permission(struct mnt_idmap *idmap, 361 361 struct inode *inode, int mask); 362 362 363 - int orangefs_update_time(struct inode *, int); 363 + int orangefs_update_time(struct inode *inode, enum fs_update_time type, 364 + unsigned int flags); 364 365 365 366 /* 366 367 * defined in xattr.c
+5 -2
fs/overlayfs/inode.c
··· 555 555 } 556 556 #endif 557 557 558 - int ovl_update_time(struct inode *inode, int flags) 558 + int ovl_update_time(struct inode *inode, enum fs_update_time type, 559 + unsigned int flags) 559 560 { 560 - if (flags & S_ATIME) { 561 + if (type == FS_UPD_ATIME) { 561 562 struct ovl_fs *ofs = OVL_FS(inode->i_sb); 562 563 struct path upperpath = { 563 564 .mnt = ovl_upper_mnt(ofs), ··· 566 565 }; 567 566 568 567 if (upperpath.dentry) { 568 + if (flags & IOCB_NOWAIT) 569 + return -EAGAIN; 569 570 touch_atime(&upperpath); 570 571 inode_set_atime_to_ts(inode, 571 572 inode_get_atime(d_inode(upperpath.dentry)));
+2 -1
fs/overlayfs/overlayfs.h
··· 820 820 } 821 821 #endif 822 822 823 - int ovl_update_time(struct inode *inode, int flags); 823 + int ovl_update_time(struct inode *inode, enum fs_update_time type, 824 + unsigned int flags); 824 825 bool ovl_is_private_xattr(struct super_block *sb, const char *name); 825 826 826 827 struct ovl_inode_params {
+2 -2
fs/sync.c
··· 183 183 184 184 if (!file->f_op->fsync) 185 185 return -EINVAL; 186 - if (!datasync && (inode_state_read_once(inode) & I_DIRTY_TIME)) 187 - mark_inode_dirty_sync(inode); 186 + if (!datasync) 187 + sync_lazytime(inode); 188 188 return file->f_op->fsync(file, start, end, datasync); 189 189 } 190 190 EXPORT_SYMBOL(vfs_fsync_range);
+12 -16
fs/ubifs/file.c
··· 1361 1361 return 0; 1362 1362 } 1363 1363 1364 - /** 1365 - * ubifs_update_time - update time of inode. 1366 - * @inode: inode to update 1367 - * @flags: time updating control flag determines updating 1368 - * which time fields of @inode 1369 - * 1370 - * This function updates time of the inode. 1371 - * 1372 - * Returns: %0 for success or a negative error code otherwise. 1373 - */ 1374 - int ubifs_update_time(struct inode *inode, int flags) 1364 + int ubifs_update_time(struct inode *inode, enum fs_update_time type, 1365 + unsigned int flags) 1375 1366 { 1376 1367 struct ubifs_inode *ui = ubifs_inode(inode); 1377 1368 struct ubifs_info *c = inode->i_sb->s_fs_info; ··· 1370 1379 .dirtied_ino_d = ALIGN(ui->data_len, 8) }; 1371 1380 int err, release; 1372 1381 1373 - if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) { 1374 - generic_update_time(inode, flags); 1375 - return 0; 1376 - } 1382 + /* ubifs sets S_NOCMTIME on all inodes, this should not happen. */ 1383 + if (WARN_ON_ONCE(type != FS_UPD_ATIME)) 1384 + return -EIO; 1385 + 1386 + if (!IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) 1387 + return generic_update_time(inode, type, flags); 1388 + 1389 + if (flags & IOCB_NOWAIT) 1390 + return -EAGAIN; 1377 1391 1378 1392 err = ubifs_budget_space(c, &req); 1379 1393 if (err) 1380 1394 return err; 1381 1395 1382 1396 mutex_lock(&ui->ui_mutex); 1383 - inode_update_timestamps(inode, flags); 1397 + inode_update_time(inode, type, flags); 1384 1398 release = ui->dirty; 1385 1399 __mark_inode_dirty(inode, I_DIRTY_SYNC); 1386 1400 mutex_unlock(&ui->ui_mutex);
+2 -1
fs/ubifs/ubifs.h
··· 2018 2018 int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync); 2019 2019 int ubifs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 2020 2020 struct iattr *attr); 2021 - int ubifs_update_time(struct inode *inode, int flags); 2021 + int ubifs_update_time(struct inode *inode, enum fs_update_time type, 2022 + unsigned int flags); 2022 2023 2023 2024 /* dir.c */ 2024 2025 struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
+35 -14
fs/xfs/xfs_iops.c
··· 1184 1184 STATIC int 1185 1185 xfs_vn_update_time( 1186 1186 struct inode *inode, 1187 - int flags) 1187 + enum fs_update_time type, 1188 + unsigned int flags) 1188 1189 { 1189 1190 struct xfs_inode *ip = XFS_I(inode); 1190 1191 struct xfs_mount *mp = ip->i_mount; 1191 1192 int log_flags = XFS_ILOG_TIMESTAMP; 1192 1193 struct xfs_trans *tp; 1193 1194 int error; 1194 - struct timespec64 now; 1195 1195 1196 1196 trace_xfs_update_time(ip); 1197 1197 1198 1198 if (inode->i_sb->s_flags & SB_LAZYTIME) { 1199 - if (!((flags & S_VERSION) && 1200 - inode_maybe_inc_iversion(inode, false))) { 1201 - generic_update_time(inode, flags); 1199 + int dirty; 1200 + 1201 + dirty = inode_update_time(inode, type, flags); 1202 + if (dirty <= 0) 1203 + return dirty; 1204 + if (dirty == I_DIRTY_TIME) { 1205 + __mark_inode_dirty(inode, I_DIRTY_TIME); 1202 1206 return 0; 1203 1207 } 1204 1208 1205 1209 /* Capture the iversion update that just occurred */ 1206 1210 log_flags |= XFS_ILOG_CORE; 1211 + } else { 1212 + if (flags & IOCB_NOWAIT) 1213 + return -EAGAIN; 1207 1214 } 1208 1215 1209 1216 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp); ··· 1218 1211 return error; 1219 1212 1220 1213 xfs_ilock(ip, XFS_ILOCK_EXCL); 1221 - if (flags & (S_CTIME|S_MTIME)) 1222 - now = inode_set_ctime_current(inode); 1214 + if (type == FS_UPD_ATIME) 1215 + inode_set_atime_to_ts(inode, current_time(inode)); 1223 1216 else 1224 - now = current_time(inode); 1225 - 1226 - if (flags & S_MTIME) 1227 - inode_set_mtime_to_ts(inode, now); 1228 - if (flags & S_ATIME) 1229 - inode_set_atime_to_ts(inode, now); 1230 - 1217 + inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); 1231 1218 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1232 1219 xfs_trans_log_inode(tp, ip, log_flags); 1233 1220 return xfs_trans_commit(tp); 1221 + } 1222 + 1223 + static void 1224 + xfs_vn_sync_lazytime( 1225 + struct inode *inode) 1226 + { 1227 + struct xfs_inode *ip = XFS_I(inode); 1228 + struct xfs_mount *mp = ip->i_mount; 1229 + struct xfs_trans *tp; 1230 + 1231 + if (xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp)) 1232 + return; 1233 + xfs_ilock(ip, XFS_ILOCK_EXCL); 1234 + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1235 + xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); 1236 + xfs_trans_commit(tp); 1234 1237 } 1235 1238 1236 1239 STATIC int ··· 1286 1269 .listxattr = xfs_vn_listxattr, 1287 1270 .fiemap = xfs_vn_fiemap, 1288 1271 .update_time = xfs_vn_update_time, 1272 + .sync_lazytime = xfs_vn_sync_lazytime, 1289 1273 .fileattr_get = xfs_fileattr_get, 1290 1274 .fileattr_set = xfs_fileattr_set, 1291 1275 }; ··· 1313 1295 .setattr = xfs_vn_setattr, 1314 1296 .listxattr = xfs_vn_listxattr, 1315 1297 .update_time = xfs_vn_update_time, 1298 + .sync_lazytime = xfs_vn_sync_lazytime, 1316 1299 .tmpfile = xfs_vn_tmpfile, 1317 1300 .fileattr_get = xfs_fileattr_get, 1318 1301 .fileattr_set = xfs_fileattr_set, ··· 1341 1322 .setattr = xfs_vn_setattr, 1342 1323 .listxattr = xfs_vn_listxattr, 1343 1324 .update_time = xfs_vn_update_time, 1325 + .sync_lazytime = xfs_vn_sync_lazytime, 1344 1326 .tmpfile = xfs_vn_tmpfile, 1345 1327 .fileattr_get = xfs_fileattr_get, 1346 1328 .fileattr_set = xfs_fileattr_set, ··· 1353 1333 .setattr = xfs_vn_setattr, 1354 1334 .listxattr = xfs_vn_listxattr, 1355 1335 .update_time = xfs_vn_update_time, 1336 + .sync_lazytime = xfs_vn_sync_lazytime, 1356 1337 .fileattr_get = xfs_fileattr_get, 1357 1338 .fileattr_set = xfs_fileattr_set, 1358 1339 };
-29
fs/xfs/xfs_super.c
··· 712 712 xfs_inode_mark_reclaimable(ip); 713 713 } 714 714 715 - static void 716 - xfs_fs_dirty_inode( 717 - struct inode *inode, 718 - int flags) 719 - { 720 - struct xfs_inode *ip = XFS_I(inode); 721 - struct xfs_mount *mp = ip->i_mount; 722 - struct xfs_trans *tp; 723 - 724 - if (!(inode->i_sb->s_flags & SB_LAZYTIME)) 725 - return; 726 - 727 - /* 728 - * Only do the timestamp update if the inode is dirty (I_DIRTY_SYNC) 729 - * and has dirty timestamp (I_DIRTY_TIME). I_DIRTY_TIME can be passed 730 - * in flags possibly together with I_DIRTY_SYNC. 731 - */ 732 - if ((flags & ~I_DIRTY_TIME) != I_DIRTY_SYNC || !(flags & I_DIRTY_TIME)) 733 - return; 734 - 735 - if (xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp)) 736 - return; 737 - xfs_ilock(ip, XFS_ILOCK_EXCL); 738 - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 739 - xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); 740 - xfs_trans_commit(tp); 741 - } 742 - 743 715 /* 744 716 * Slab object creation initialisation for the XFS inode. 745 717 * This covers only the idempotent fields in the XFS inode; ··· 1276 1304 static const struct super_operations xfs_super_operations = { 1277 1305 .alloc_inode = xfs_fs_alloc_inode, 1278 1306 .destroy_inode = xfs_fs_destroy_inode, 1279 - .dirty_inode = xfs_fs_dirty_inode, 1280 1307 .drop_inode = xfs_fs_drop_inode, 1281 1308 .evict_inode = xfs_fs_evict_inode, 1282 1309 .put_super = xfs_fs_put_super,
+19 -11
include/linux/fs.h
··· 1717 1717 1718 1718 struct timespec64 simple_inode_init_ts(struct inode *inode); 1719 1719 1720 + static inline int inode_time_dirty_flag(struct inode *inode) 1721 + { 1722 + if (inode->i_sb->s_flags & SB_LAZYTIME) 1723 + return I_DIRTY_TIME; 1724 + return I_DIRTY_SYNC; 1725 + } 1726 + 1720 1727 /* 1721 1728 * Snapshotting support. 1722 1729 */ ··· 1992 1985 static int shared_##x(struct file *file , struct dir_context *ctx) \ 1993 1986 { return wrap_directory_iterator(file, ctx, x); } 1994 1987 1988 + enum fs_update_time { 1989 + FS_UPD_ATIME, 1990 + FS_UPD_CMTIME, 1991 + }; 1992 + 1995 1993 struct inode_operations { 1996 1994 struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); 1997 1995 const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *); ··· 2024 2012 ssize_t (*listxattr) (struct dentry *, char *, size_t); 2025 2013 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, 2026 2014 u64 len); 2027 - int (*update_time)(struct inode *, int); 2015 + int (*update_time)(struct inode *inode, enum fs_update_time type, 2016 + unsigned int flags); 2017 + void (*sync_lazytime)(struct inode *inode); 2028 2018 int (*atomic_open)(struct inode *, struct dentry *, 2029 2019 struct file *, unsigned open_flag, 2030 2020 umode_t create_mode); ··· 2253 2239 mark_inode_dirty(inode); 2254 2240 } 2255 2241 2256 - enum file_time_flags { 2257 - S_ATIME = 1, 2258 - S_MTIME = 2, 2259 - S_CTIME = 4, 2260 - S_VERSION = 8, 2261 - }; 2262 - 2263 2242 extern bool atime_needs_update(const struct path *, struct inode *); 2264 2243 extern void touch_atime(const struct path *); 2265 - int inode_update_time(struct inode *inode, int flags); 2266 2244 2267 2245 static inline void file_accessed(struct file *file) 2268 2246 { ··· 2407 2401 extern void ihold(struct inode * inode); 2408 2402 extern void iput(struct inode *); 2409 2403 void iput_not_last(struct inode *); 2410 - int inode_update_timestamps(struct inode *inode, int flags); 2411 - int generic_update_time(struct inode *, int); 2404 + int inode_update_time(struct inode *inode, enum fs_update_time type, 2405 + unsigned int flags); 2406 + int generic_update_time(struct inode *inode, enum fs_update_time type, 2407 + unsigned int flags); 2412 2408 2413 2409 /* /sys/fs */ 2414 2410 extern struct kobject *fs_kobj;
-6
include/trace/events/writeback.h
··· 856 856 TP_ARGS(inode) 857 857 ); 858 858 859 - DEFINE_EVENT(writeback_inode_template, writeback_lazytime_iput, 860 - TP_PROTO(struct inode *inode), 861 - 862 - TP_ARGS(inode) 863 - ); 864 - 865 859 DEFINE_EVENT(writeback_inode_template, writeback_dirty_inode_enqueue, 866 860 867 861 TP_PROTO(struct inode *inode),