1 vfs: split update_time() into update_time() and write_time()
3 In preparation for adding support for the lazytime mount option, we
4 need to be able to separate out the update_time() and write_time()
5 inode operations. Currently, only btrfs and xfs uses update_time().
7 We needed to preserve update_time() because btrfs wants to have a
8 special btrfs_root_readonly() check; otherwise we could drop the
9 update_time() inode operation entirely.
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 Cc: linux-btrfs@vger.kernel.org
14 Acked-by: David Sterba <dsterba@suse.cz>
16 Documentation/filesystems/Locking | 2 ++
17 fs/btrfs/inode.c | 10 ++++++++++
18 fs/inode.c | 29 ++++++++++++++++++-----------
19 fs/xfs/xfs_iops.c | 39 ++++++++++++++++-----------------------
20 include/linux/fs.h | 1 +
21 5 files changed, 47 insertions(+), 34 deletions(-)
23 diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
24 index b30753c..e49861d 100644
25 --- a/Documentation/filesystems/Locking
26 +++ b/Documentation/filesystems/Locking
27 @@ -63,6 +63,7 @@ prototypes:
28 int (*removexattr) (struct dentry *, const char *);
29 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
30 void (*update_time)(struct inode *, struct timespec *, int);
31 + void (*write_time)(struct inode *);
32 int (*atomic_open)(struct inode *, struct dentry *,
33 struct file *, unsigned open_flag,
34 umode_t create_mode, int *opened);
35 @@ -95,6 +96,7 @@ listxattr: no
43 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
44 index d23362f..a5e0d0d 100644
45 --- a/fs/btrfs/inode.c
46 +++ b/fs/btrfs/inode.c
47 @@ -5574,6 +5574,11 @@ static int btrfs_update_time(struct inode *inode, struct timespec *now,
48 inode->i_mtime = *now;
50 inode->i_atime = *now;
54 +static int btrfs_write_time(struct inode *inode)
56 return btrfs_dirty_inode(inode);
59 @@ -9462,6 +9467,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
60 .get_acl = btrfs_get_acl,
61 .set_acl = btrfs_set_acl,
62 .update_time = btrfs_update_time,
63 + .write_time = btrfs_write_time,
64 .tmpfile = btrfs_tmpfile,
66 static const struct inode_operations btrfs_dir_ro_inode_operations = {
67 @@ -9470,6 +9476,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
68 .get_acl = btrfs_get_acl,
69 .set_acl = btrfs_set_acl,
70 .update_time = btrfs_update_time,
71 + .write_time = btrfs_write_time,
74 static const struct file_operations btrfs_dir_file_operations = {
75 @@ -9540,6 +9547,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
76 .get_acl = btrfs_get_acl,
77 .set_acl = btrfs_set_acl,
78 .update_time = btrfs_update_time,
79 + .write_time = btrfs_write_time,
81 static const struct inode_operations btrfs_special_inode_operations = {
82 .getattr = btrfs_getattr,
83 @@ -9552,6 +9560,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
84 .get_acl = btrfs_get_acl,
85 .set_acl = btrfs_set_acl,
86 .update_time = btrfs_update_time,
87 + .write_time = btrfs_write_time,
89 static const struct inode_operations btrfs_symlink_inode_operations = {
90 .readlink = generic_readlink,
91 @@ -9565,6 +9574,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
92 .listxattr = btrfs_listxattr,
93 .removexattr = btrfs_removexattr,
94 .update_time = btrfs_update_time,
95 + .write_time = btrfs_write_time,
98 const struct dentry_operations btrfs_dentry_operations = {
99 diff --git a/fs/inode.c b/fs/inode.c
100 index 26753ba..8f5c4b5 100644
103 @@ -1499,17 +1499,24 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
105 static int update_time(struct inode *inode, struct timespec *time, int flags)
107 - if (inode->i_op->update_time)
108 - return inode->i_op->update_time(inode, time, flags);
110 - if (flags & S_ATIME)
111 - inode->i_atime = *time;
112 - if (flags & S_VERSION)
113 - inode_inc_iversion(inode);
114 - if (flags & S_CTIME)
115 - inode->i_ctime = *time;
116 - if (flags & S_MTIME)
117 - inode->i_mtime = *time;
120 + if (inode->i_op->update_time) {
121 + ret = inode->i_op->update_time(inode, time, flags);
125 + if (flags & S_ATIME)
126 + inode->i_atime = *time;
127 + if (flags & S_VERSION)
128 + inode_inc_iversion(inode);
129 + if (flags & S_CTIME)
130 + inode->i_ctime = *time;
131 + if (flags & S_MTIME)
132 + inode->i_mtime = *time;
134 + if (inode->i_op->write_time)
135 + return inode->i_op->write_time(inode);
136 mark_inode_dirty_sync(inode);
139 diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
140 index ec6dcdc..0e9653c 100644
141 --- a/fs/xfs/xfs_iops.c
142 +++ b/fs/xfs/xfs_iops.c
143 @@ -984,10 +984,8 @@ xfs_vn_setattr(
148 - struct inode *inode,
149 - struct timespec *now,
152 + struct inode *inode)
154 struct xfs_inode *ip = XFS_I(inode);
155 struct xfs_mount *mp = ip->i_mount;
156 @@ -1004,21 +1002,16 @@ xfs_vn_update_time(
159 xfs_ilock(ip, XFS_ILOCK_EXCL);
160 - if (flags & S_CTIME) {
161 - inode->i_ctime = *now;
162 - ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
163 - ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
165 - if (flags & S_MTIME) {
166 - inode->i_mtime = *now;
167 - ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
168 - ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
170 - if (flags & S_ATIME) {
171 - inode->i_atime = *now;
172 - ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
173 - ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
176 + ip->i_d.di_ctime.t_sec = (__int32_t) inode->i_ctime.tv_sec;
177 + ip->i_d.di_ctime.t_nsec = (__int32_t) inode->i_ctime.tv_nsec;
179 + ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
180 + ip->i_d.di_mtime.t_nsec = (__int32_t) inode->i_mtime.tv_nsec;
182 + ip->i_d.di_atime.t_sec = (__int32_t) inode->i_atime.tv_sec;
183 + ip->i_d.di_atime.t_nsec = (__int32_t) inode->i_atime.tv_nsec;
185 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
186 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
187 return xfs_trans_commit(tp, 0);
188 @@ -1129,7 +1122,7 @@ static const struct inode_operations xfs_inode_operations = {
189 .removexattr = generic_removexattr,
190 .listxattr = xfs_vn_listxattr,
191 .fiemap = xfs_vn_fiemap,
192 - .update_time = xfs_vn_update_time,
193 + .write_time = xfs_vn_write_time,
196 static const struct inode_operations xfs_dir_inode_operations = {
197 @@ -1156,7 +1149,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
198 .getxattr = generic_getxattr,
199 .removexattr = generic_removexattr,
200 .listxattr = xfs_vn_listxattr,
201 - .update_time = xfs_vn_update_time,
202 + .write_time = xfs_vn_write_time,
203 .tmpfile = xfs_vn_tmpfile,
206 @@ -1184,7 +1177,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
207 .getxattr = generic_getxattr,
208 .removexattr = generic_removexattr,
209 .listxattr = xfs_vn_listxattr,
210 - .update_time = xfs_vn_update_time,
211 + .write_time = xfs_vn_write_time,
212 .tmpfile = xfs_vn_tmpfile,
215 @@ -1198,7 +1191,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
216 .getxattr = generic_getxattr,
217 .removexattr = generic_removexattr,
218 .listxattr = xfs_vn_listxattr,
219 - .update_time = xfs_vn_update_time,
220 + .write_time = xfs_vn_write_time,
224 diff --git a/include/linux/fs.h b/include/linux/fs.h
225 index 9ab779e..3633239 100644
226 --- a/include/linux/fs.h
227 +++ b/include/linux/fs.h
228 @@ -1545,6 +1545,7 @@ struct inode_operations {
229 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
231 int (*update_time)(struct inode *, struct timespec *, int);
232 + int (*write_time)(struct inode *);
233 int (*atomic_open)(struct inode *, struct dentry *,
234 struct file *, unsigned open_flag,
235 umode_t create_mode, int *opened);