1 fs: 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
15 Documentation/filesystems/Locking | 2 ++
16 fs/btrfs/inode.c | 10 ++++++++++
17 fs/inode.c | 29 ++++++++++++++++++-----------
18 fs/xfs/xfs_iops.c | 39 ++++++++++++++++-----------------------
19 include/linux/fs.h | 1 +
20 5 files changed, 47 insertions(+), 34 deletions(-)
22 diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
23 index b30753c..e49861d 100644
24 --- a/Documentation/filesystems/Locking
25 +++ b/Documentation/filesystems/Locking
26 @@ -63,6 +63,7 @@ prototypes:
27 int (*removexattr) (struct dentry *, const char *);
28 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
29 void (*update_time)(struct inode *, struct timespec *, int);
30 + void (*write_time)(struct inode *);
31 int (*atomic_open)(struct inode *, struct dentry *,
32 struct file *, unsigned open_flag,
33 umode_t create_mode, int *opened);
34 @@ -95,6 +96,7 @@ listxattr: no
42 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
43 index d23362f..a5e0d0d 100644
44 --- a/fs/btrfs/inode.c
45 +++ b/fs/btrfs/inode.c
46 @@ -5574,6 +5574,11 @@ static int btrfs_update_time(struct inode *inode, struct timespec *now,
47 inode->i_mtime = *now;
49 inode->i_atime = *now;
53 +static int btrfs_write_time(struct inode *inode)
55 return btrfs_dirty_inode(inode);
58 @@ -9462,6 +9467,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
59 .get_acl = btrfs_get_acl,
60 .set_acl = btrfs_set_acl,
61 .update_time = btrfs_update_time,
62 + .write_time = btrfs_write_time,
63 .tmpfile = btrfs_tmpfile,
65 static const struct inode_operations btrfs_dir_ro_inode_operations = {
66 @@ -9470,6 +9476,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
67 .get_acl = btrfs_get_acl,
68 .set_acl = btrfs_set_acl,
69 .update_time = btrfs_update_time,
70 + .write_time = btrfs_write_time,
73 static const struct file_operations btrfs_dir_file_operations = {
74 @@ -9540,6 +9547,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
75 .get_acl = btrfs_get_acl,
76 .set_acl = btrfs_set_acl,
77 .update_time = btrfs_update_time,
78 + .write_time = btrfs_write_time,
80 static const struct inode_operations btrfs_special_inode_operations = {
81 .getattr = btrfs_getattr,
82 @@ -9552,6 +9560,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
83 .get_acl = btrfs_get_acl,
84 .set_acl = btrfs_set_acl,
85 .update_time = btrfs_update_time,
86 + .write_time = btrfs_write_time,
88 static const struct inode_operations btrfs_symlink_inode_operations = {
89 .readlink = generic_readlink,
90 @@ -9565,6 +9574,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
91 .listxattr = btrfs_listxattr,
92 .removexattr = btrfs_removexattr,
93 .update_time = btrfs_update_time,
94 + .write_time = btrfs_write_time,
97 const struct dentry_operations btrfs_dentry_operations = {
98 diff --git a/fs/inode.c b/fs/inode.c
99 index 26753ba..8f5c4b5 100644
102 @@ -1499,17 +1499,24 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
104 static int update_time(struct inode *inode, struct timespec *time, int flags)
106 - if (inode->i_op->update_time)
107 - return inode->i_op->update_time(inode, time, flags);
109 - if (flags & S_ATIME)
110 - inode->i_atime = *time;
111 - if (flags & S_VERSION)
112 - inode_inc_iversion(inode);
113 - if (flags & S_CTIME)
114 - inode->i_ctime = *time;
115 - if (flags & S_MTIME)
116 - inode->i_mtime = *time;
119 + if (inode->i_op->update_time) {
120 + ret = inode->i_op->update_time(inode, time, flags);
124 + if (flags & S_ATIME)
125 + inode->i_atime = *time;
126 + if (flags & S_VERSION)
127 + inode_inc_iversion(inode);
128 + if (flags & S_CTIME)
129 + inode->i_ctime = *time;
130 + if (flags & S_MTIME)
131 + inode->i_mtime = *time;
133 + if (inode->i_op->write_time)
134 + return inode->i_op->write_time(inode);
135 mark_inode_dirty_sync(inode);
138 diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
139 index ec6dcdc..0e9653c 100644
140 --- a/fs/xfs/xfs_iops.c
141 +++ b/fs/xfs/xfs_iops.c
142 @@ -984,10 +984,8 @@ xfs_vn_setattr(
147 - struct inode *inode,
148 - struct timespec *now,
151 + struct inode *inode)
153 struct xfs_inode *ip = XFS_I(inode);
154 struct xfs_mount *mp = ip->i_mount;
155 @@ -1004,21 +1002,16 @@ xfs_vn_update_time(
158 xfs_ilock(ip, XFS_ILOCK_EXCL);
159 - if (flags & S_CTIME) {
160 - inode->i_ctime = *now;
161 - ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
162 - ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
164 - if (flags & S_MTIME) {
165 - inode->i_mtime = *now;
166 - ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
167 - ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
169 - if (flags & S_ATIME) {
170 - inode->i_atime = *now;
171 - ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
172 - ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
175 + ip->i_d.di_ctime.t_sec = (__int32_t) inode->i_ctime.tv_sec;
176 + ip->i_d.di_ctime.t_nsec = (__int32_t) inode->i_ctime.tv_nsec;
178 + ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
179 + ip->i_d.di_mtime.t_nsec = (__int32_t) inode->i_mtime.tv_nsec;
181 + ip->i_d.di_atime.t_sec = (__int32_t) inode->i_atime.tv_sec;
182 + ip->i_d.di_atime.t_nsec = (__int32_t) inode->i_atime.tv_nsec;
184 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
185 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
186 return xfs_trans_commit(tp, 0);
187 @@ -1129,7 +1122,7 @@ static const struct inode_operations xfs_inode_operations = {
188 .removexattr = generic_removexattr,
189 .listxattr = xfs_vn_listxattr,
190 .fiemap = xfs_vn_fiemap,
191 - .update_time = xfs_vn_update_time,
192 + .write_time = xfs_vn_write_time,
195 static const struct inode_operations xfs_dir_inode_operations = {
196 @@ -1156,7 +1149,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
197 .getxattr = generic_getxattr,
198 .removexattr = generic_removexattr,
199 .listxattr = xfs_vn_listxattr,
200 - .update_time = xfs_vn_update_time,
201 + .write_time = xfs_vn_write_time,
202 .tmpfile = xfs_vn_tmpfile,
205 @@ -1184,7 +1177,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
206 .getxattr = generic_getxattr,
207 .removexattr = generic_removexattr,
208 .listxattr = xfs_vn_listxattr,
209 - .update_time = xfs_vn_update_time,
210 + .write_time = xfs_vn_write_time,
211 .tmpfile = xfs_vn_tmpfile,
214 @@ -1198,7 +1191,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
215 .getxattr = generic_getxattr,
216 .removexattr = generic_removexattr,
217 .listxattr = xfs_vn_listxattr,
218 - .update_time = xfs_vn_update_time,
219 + .write_time = xfs_vn_write_time,
223 diff --git a/include/linux/fs.h b/include/linux/fs.h
224 index 9ab779e..3633239 100644
225 --- a/include/linux/fs.h
226 +++ b/include/linux/fs.h
227 @@ -1545,6 +1545,7 @@ struct inode_operations {
228 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
230 int (*update_time)(struct inode *, struct timespec *, int);
231 + int (*write_time)(struct inode *);
232 int (*atomic_open)(struct inode *, struct dentry *,
233 struct file *, unsigned open_flag,
234 umode_t create_mode, int *opened);