Skip to content

Commit 615e958

Browse files
committed
Merge tag 'v6.6-vfs.ctime' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs timestamp updates from Christian Brauner: "This adds VFS support for multi-grain timestamps and converts tmpfs, xfs, ext4, and btrfs to use them. This carries acks from all relevant filesystems. The VFS always uses coarse-grained timestamps when updating the ctime and mtime after a change. This has the benefit of allowing filesystems to optimize away a lot of metadata updates, down to around 1 per jiffy, even when a file is under heavy writes. Unfortunately, this has always been an issue when we're exporting via NFSv3, which relies on timestamps to validate caches. A lot of changes can happen in a jiffy, so timestamps aren't sufficient to help the client decide to invalidate the cache. Even with NFSv4, a lot of exported filesystems don't properly support a change attribute and are subject to the same problems with timestamp granularity. Other applications have similar issues with timestamps (e.g., backup applications). If we were to always use fine-grained timestamps, that would improve the situation, but that becomes rather expensive, as the underlying filesystem would have to log a lot more metadata updates. This introduces fine-grained timestamps that are used when they are actively queried. This uses the 31st bit of the ctime tv_nsec field to indicate that something has queried the inode for the mtime or ctime. When this flag is set, on the next mtime or ctime update, the kernel will fetch a fine-grained timestamp instead of the usual coarse-grained one. As POSIX generally mandates that when the mtime changes, the ctime must also change the kernel always stores normalized ctime values, so only the first 30 bits of the tv_nsec field are ever used. Filesytems can opt into this behavior by setting the FS_MGTIME flag in the fstype. Filesystems that don't set this flag will continue to use coarse-grained timestamps. Various preparatory changes, fixes and cleanups are included: - Fixup all relevant places where POSIX requires updating ctime together with mtime. This is a wide-range of places and all maintainers provided necessary Acks. - Add new accessors for inode->i_ctime directly and change all callers to rely on them. Plain accesses to inode->i_ctime are now gone and it is accordingly rename to inode->__i_ctime and commented as requiring accessors. - Extend generic_fillattr() to pass in a request mask mirroring in a sense the statx() uapi. This allows callers to pass in a request mask to only get a subset of attributes filled in. - Rework timestamp updates so it's possible to drop the @now parameter the update_time() inode operation and associated helpers. - Add inode_update_timestamps() and convert all filesystems to it removing a bunch of open-coding" * tag 'v6.6-vfs.ctime' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (107 commits) btrfs: convert to multigrain timestamps ext4: switch to multigrain timestamps xfs: switch to multigrain timestamps tmpfs: add support for multigrain timestamps fs: add infrastructure for multigrain timestamps fs: drop the timespec64 argument from update_time xfs: have xfs_vn_update_time gets its own timestamp fat: make fat_update_time get its own timestamp fat: remove i_version handling from fat_update_time ubifs: have ubifs_update_time use inode_update_timestamps btrfs: have it use inode_update_timestamps fs: drop the timespec64 arg from generic_update_time fs: pass the request_mask to generic_fillattr fs: remove silly warning from current_time gfs2: fix timestamp handling on quota inodes fs: rename i_ctime field to __i_ctime selinux: convert to ctime accessor functions security: convert to ctime accessor functions apparmor: convert to ctime accessor functions sunrpc: convert to ctime accessor functions ...
2 parents 84ab127 + 50e9cee commit 615e958

File tree

252 files changed

+1267
-1049
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

252 files changed

+1267
-1049
lines changed

arch/powerpc/platforms/cell/spufs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ spufs_new_inode(struct super_block *sb, umode_t mode)
8686
inode->i_mode = mode;
8787
inode->i_uid = current_fsuid();
8888
inode->i_gid = current_fsgid();
89-
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
89+
inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
9090
out:
9191
return inode;
9292
}

arch/s390/hypfs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void hypfs_update_update(struct super_block *sb)
5353
struct inode *inode = d_inode(sb_info->update_file);
5454

5555
sb_info->last_update = ktime_get_seconds();
56-
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
56+
inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
5757
}
5858

5959
/* directory tree removal functions */
@@ -101,7 +101,7 @@ static struct inode *hypfs_make_inode(struct super_block *sb, umode_t mode)
101101
ret->i_mode = mode;
102102
ret->i_uid = hypfs_info->uid;
103103
ret->i_gid = hypfs_info->gid;
104-
ret->i_atime = ret->i_mtime = ret->i_ctime = current_time(ret);
104+
ret->i_atime = ret->i_mtime = inode_set_ctime_current(ret);
105105
if (S_ISDIR(mode))
106106
set_nlink(ret, 2);
107107
}

drivers/android/binderfs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
153153
goto err;
154154

155155
inode->i_ino = minor + INODE_OFFSET;
156-
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
156+
inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
157157
init_special_inode(inode, S_IFCHR | 0600,
158158
MKDEV(MAJOR(binderfs_dev), minor));
159159
inode->i_fop = &binder_fops;
@@ -432,7 +432,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
432432
}
433433

434434
inode->i_ino = SECOND_INODE;
435-
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
435+
inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
436436
init_special_inode(inode, S_IFCHR | 0600,
437437
MKDEV(MAJOR(binderfs_dev), minor));
438438
inode->i_fop = &binder_ctl_fops;
@@ -474,7 +474,7 @@ static struct inode *binderfs_make_inode(struct super_block *sb, int mode)
474474
if (ret) {
475475
ret->i_ino = iunique(sb, BINDERFS_MAX_MINOR + INODE_OFFSET);
476476
ret->i_mode = mode;
477-
ret->i_atime = ret->i_mtime = ret->i_ctime = current_time(ret);
477+
ret->i_atime = ret->i_mtime = inode_set_ctime_current(ret);
478478
}
479479
return ret;
480480
}
@@ -703,7 +703,7 @@ static int binderfs_fill_super(struct super_block *sb, struct fs_context *fc)
703703
inode->i_ino = FIRST_INODE;
704704
inode->i_fop = &simple_dir_operations;
705705
inode->i_mode = S_IFDIR | 0755;
706-
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
706+
inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
707707
inode->i_op = &binderfs_dir_inode_operations;
708708
set_nlink(inode, 2);
709709

drivers/infiniband/hw/qib/qib_fs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,8 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
6464
inode->i_uid = GLOBAL_ROOT_UID;
6565
inode->i_gid = GLOBAL_ROOT_GID;
6666
inode->i_blocks = 0;
67-
inode->i_atime = current_time(inode);
67+
inode->i_atime = inode_set_ctime_current(inode);
6868
inode->i_mtime = inode->i_atime;
69-
inode->i_ctime = inode->i_atime;
7069
inode->i_private = data;
7170
if (S_ISDIR(mode)) {
7271
inode->i_op = &simple_dir_inode_operations;

drivers/misc/ibmasm/ibmasmfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
139139
if (ret) {
140140
ret->i_ino = get_next_ino();
141141
ret->i_mode = mode;
142-
ret->i_atime = ret->i_mtime = ret->i_ctime = current_time(ret);
142+
ret->i_atime = ret->i_mtime = inode_set_ctime_current(ret);
143143
}
144144
return ret;
145145
}

drivers/misc/ibmvmc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ static ssize_t ibmvmc_write(struct file *file, const char *buffer,
11241124
goto out;
11251125

11261126
inode = file_inode(file);
1127-
inode->i_mtime = current_time(inode);
1127+
inode->i_mtime = inode_set_ctime_current(inode);
11281128
mark_inode_dirty(inode);
11291129

11301130
dev_dbg(adapter->dev, "write: file = 0x%lx, count = 0x%lx\n",

drivers/usb/core/devio.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,21 +2642,21 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
26422642
snoop(&dev->dev, "%s: CONTROL\n", __func__);
26432643
ret = proc_control(ps, p);
26442644
if (ret >= 0)
2645-
inode->i_mtime = inode->i_ctime = current_time(inode);
2645+
inode->i_mtime = inode_set_ctime_current(inode);
26462646
break;
26472647

26482648
case USBDEVFS_BULK:
26492649
snoop(&dev->dev, "%s: BULK\n", __func__);
26502650
ret = proc_bulk(ps, p);
26512651
if (ret >= 0)
2652-
inode->i_mtime = inode->i_ctime = current_time(inode);
2652+
inode->i_mtime = inode_set_ctime_current(inode);
26532653
break;
26542654

26552655
case USBDEVFS_RESETEP:
26562656
snoop(&dev->dev, "%s: RESETEP\n", __func__);
26572657
ret = proc_resetep(ps, p);
26582658
if (ret >= 0)
2659-
inode->i_mtime = inode->i_ctime = current_time(inode);
2659+
inode->i_mtime = inode_set_ctime_current(inode);
26602660
break;
26612661

26622662
case USBDEVFS_RESET:
@@ -2668,7 +2668,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
26682668
snoop(&dev->dev, "%s: CLEAR_HALT\n", __func__);
26692669
ret = proc_clearhalt(ps, p);
26702670
if (ret >= 0)
2671-
inode->i_mtime = inode->i_ctime = current_time(inode);
2671+
inode->i_mtime = inode_set_ctime_current(inode);
26722672
break;
26732673

26742674
case USBDEVFS_GETDRIVER:
@@ -2695,22 +2695,22 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
26952695
snoop(&dev->dev, "%s: SUBMITURB\n", __func__);
26962696
ret = proc_submiturb(ps, p);
26972697
if (ret >= 0)
2698-
inode->i_mtime = inode->i_ctime = current_time(inode);
2698+
inode->i_mtime = inode_set_ctime_current(inode);
26992699
break;
27002700

27012701
#ifdef CONFIG_COMPAT
27022702
case USBDEVFS_CONTROL32:
27032703
snoop(&dev->dev, "%s: CONTROL32\n", __func__);
27042704
ret = proc_control_compat(ps, p);
27052705
if (ret >= 0)
2706-
inode->i_mtime = inode->i_ctime = current_time(inode);
2706+
inode->i_mtime = inode_set_ctime_current(inode);
27072707
break;
27082708

27092709
case USBDEVFS_BULK32:
27102710
snoop(&dev->dev, "%s: BULK32\n", __func__);
27112711
ret = proc_bulk_compat(ps, p);
27122712
if (ret >= 0)
2713-
inode->i_mtime = inode->i_ctime = current_time(inode);
2713+
inode->i_mtime = inode_set_ctime_current(inode);
27142714
break;
27152715

27162716
case USBDEVFS_DISCSIGNAL32:
@@ -2722,7 +2722,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
27222722
snoop(&dev->dev, "%s: SUBMITURB32\n", __func__);
27232723
ret = proc_submiturb_compat(ps, p);
27242724
if (ret >= 0)
2725-
inode->i_mtime = inode->i_ctime = current_time(inode);
2725+
inode->i_mtime = inode_set_ctime_current(inode);
27262726
break;
27272727

27282728
case USBDEVFS_IOCTL32:

drivers/usb/gadget/function/f_fs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,15 +1377,14 @@ ffs_sb_make_inode(struct super_block *sb, void *data,
13771377
inode = new_inode(sb);
13781378

13791379
if (inode) {
1380-
struct timespec64 ts = current_time(inode);
1380+
struct timespec64 ts = inode_set_ctime_current(inode);
13811381

13821382
inode->i_ino = get_next_ino();
13831383
inode->i_mode = perms->mode;
13841384
inode->i_uid = perms->uid;
13851385
inode->i_gid = perms->gid;
13861386
inode->i_atime = ts;
13871387
inode->i_mtime = ts;
1388-
inode->i_ctime = ts;
13891388
inode->i_private = data;
13901389
if (fops)
13911390
inode->i_fop = fops;

drivers/usb/gadget/legacy/inode.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,8 +1969,7 @@ gadgetfs_make_inode (struct super_block *sb,
19691969
inode->i_mode = mode;
19701970
inode->i_uid = make_kuid(&init_user_ns, default_uid);
19711971
inode->i_gid = make_kgid(&init_user_ns, default_gid);
1972-
inode->i_atime = inode->i_mtime = inode->i_ctime
1973-
= current_time(inode);
1972+
inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
19741973
inode->i_private = data;
19751974
inode->i_fop = fops;
19761975
}

fs/9p/vfs_inode.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
260260
inode_init_owner(&nop_mnt_idmap, inode, NULL, mode);
261261
inode->i_blocks = 0;
262262
inode->i_rdev = rdev;
263-
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
263+
inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
264264
inode->i_mapping->a_ops = &v9fs_addr_operations;
265265
inode->i_private = NULL;
266266

@@ -1011,7 +1011,7 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
10111011
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
10121012
v9ses = v9fs_dentry2v9ses(dentry);
10131013
if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
1014-
generic_fillattr(&nop_mnt_idmap, inode, stat);
1014+
generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
10151015
return 0;
10161016
} else if (v9ses->cache & CACHE_WRITEBACK) {
10171017
if (S_ISREG(inode->i_mode)) {
@@ -1032,7 +1032,7 @@ v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
10321032
return PTR_ERR(st);
10331033

10341034
v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb, 0);
1035-
generic_fillattr(&nop_mnt_idmap, d_inode(dentry), stat);
1035+
generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), stat);
10361036

10371037
p9stat_free(st);
10381038
kfree(st);
@@ -1152,7 +1152,7 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
11521152

11531153
inode->i_atime.tv_sec = stat->atime;
11541154
inode->i_mtime.tv_sec = stat->mtime;
1155-
inode->i_ctime.tv_sec = stat->mtime;
1155+
inode_set_ctime(inode, stat->mtime, 0);
11561156

11571157
inode->i_uid = v9ses->dfltuid;
11581158
inode->i_gid = v9ses->dfltgid;

0 commit comments

Comments
 (0)