lazytime -v7 patches
[ext4-patch-queue.git] / split-update_time-into-update_time-and-write_time
blob394aef6eeda7d1d1c1c5fb86abc18d1e40c7e892
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.  Previously, only btrfs and xfs uses update_time().
7 With this patch, btrfs only needs write_time(), and xfs uses
8 update_time() to synchronize its on-disk and in-memory timestamps.
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
11 Cc: xfs@oss.sgi.com
12 Cc: linux-btrfs@vger.kernel.org
13 Acked-by: David Sterba <dsterba@suse.cz>
14 ---
15  Documentation/filesystems/Locking |  4 +++-
16  fs/btrfs/inode.c                  | 30 ++++++------------------------
17  fs/inode.c                        |  7 ++++---
18  fs/xfs/xfs_iops.c                 | 48 ++++++++++++++++++++++++++----------------------
19  fs/xfs/xfs_trace.h                |  1 +
20  include/linux/fs.h                |  3 ++-
21  6 files changed, 42 insertions(+), 51 deletions(-)
23 diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
24 index b30753c..ee94a66 100644
25 --- a/Documentation/filesystems/Locking
26 +++ b/Documentation/filesystems/Locking
27 @@ -62,7 +62,8 @@ prototypes:
28         ssize_t (*listxattr) (struct dentry *, char *, size_t);
29         int (*removexattr) (struct dentry *, const char *);
30         int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
31 -       void (*update_time)(struct inode *, struct timespec *, int);
32 +       void (*update_time)(struct inode *);
33 +       void (*write_time)(struct inode *);
34         int (*atomic_open)(struct inode *, struct dentry *,
35                                 struct file *, unsigned open_flag,
36                                 umode_t create_mode, int *opened);
37 @@ -95,6 +96,7 @@ listxattr:    no
38  removexattr:   yes
39  fiemap:                no
40  update_time:   no
41 +write_time:    no
42  atomic_open:   yes
43  tmpfile:       no
44  dentry_open:   no
45 diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
46 index bd46a22..a81a0652 100644
47 --- a/fs/btrfs/inode.c
48 +++ b/fs/btrfs/inode.c
49 @@ -5563,26 +5563,8 @@ static int btrfs_is_readonly(struct inode *inode)
50         return 0;
51  }
53 -/*
54 - * This is a copy of file_update_time.  We need this so we can return error on
55 - * ENOSPC for updating the inode in the case of file write and mmap writes.
56 - */
57 -static int btrfs_update_time(struct inode *inode, struct timespec *now,
58 -                            int flags)
59 +static int btrfs_write_time(struct inode *inode)
60  {
61 -       struct btrfs_root *root = BTRFS_I(inode)->root;
63 -       if (btrfs_root_readonly(root))
64 -               return -EROFS;
66 -       if (flags & S_VERSION)
67 -               inode_inc_iversion(inode);
68 -       if (flags & S_CTIME)
69 -               inode->i_ctime = *now;
70 -       if (flags & S_MTIME)
71 -               inode->i_mtime = *now;
72 -       if (flags & S_ATIME)
73 -               inode->i_atime = *now;
74         return btrfs_dirty_inode(inode);
75  }
77 @@ -9471,7 +9453,7 @@ static const struct inode_operations btrfs_dir_inode_operations = {
78         .get_acl        = btrfs_get_acl,
79         .set_acl        = btrfs_set_acl,
80         .is_readonly    = btrfs_is_readonly,
81 -       .update_time    = btrfs_update_time,
82 +       .write_time     = btrfs_write_time,
83         .tmpfile        = btrfs_tmpfile,
84  };
85  static const struct inode_operations btrfs_dir_ro_inode_operations = {
86 @@ -9480,7 +9462,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
87         .get_acl        = btrfs_get_acl,
88         .set_acl        = btrfs_set_acl,
89         .is_readonly    = btrfs_is_readonly,
90 -       .update_time    = btrfs_update_time,
91 +       .write_time     = btrfs_write_time,
92  };
94  static const struct file_operations btrfs_dir_file_operations = {
95 @@ -9551,7 +9533,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
96         .get_acl        = btrfs_get_acl,
97         .set_acl        = btrfs_set_acl,
98         .is_readonly    = btrfs_is_readonly,
99 -       .update_time    = btrfs_update_time,
100 +       .write_time     = btrfs_write_time,
101  };
102  static const struct inode_operations btrfs_special_inode_operations = {
103         .getattr        = btrfs_getattr,
104 @@ -9564,7 +9546,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
105         .get_acl        = btrfs_get_acl,
106         .set_acl        = btrfs_set_acl,
107         .is_readonly    = btrfs_is_readonly,
108 -       .update_time    = btrfs_update_time,
109 +       .write_time     = btrfs_write_time,
110  };
111  static const struct inode_operations btrfs_symlink_inode_operations = {
112         .readlink       = generic_readlink,
113 @@ -9578,7 +9560,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
114         .listxattr      = btrfs_listxattr,
115         .removexattr    = btrfs_removexattr,
116         .is_readonly    = btrfs_is_readonly,
117 -       .update_time    = btrfs_update_time,
118 +       .write_time     = btrfs_write_time,
119  };
121  const struct dentry_operations btrfs_dentry_operations = {
122 diff --git a/fs/inode.c b/fs/inode.c
123 index 53f0173..94bc908 100644
124 --- a/fs/inode.c
125 +++ b/fs/inode.c
126 @@ -1506,9 +1506,6 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
127                 if (ret)
128                         return ret;
129         }
130 -       if (inode->i_op->update_time)
131 -               return inode->i_op->update_time(inode, time, flags);
133         if (flags & S_ATIME)
134                 inode->i_atime = *time;
135         if (flags & S_VERSION)
136 @@ -1517,6 +1514,10 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
137                 inode->i_ctime = *time;
138         if (flags & S_MTIME)
139                 inode->i_mtime = *time;
140 +       if (inode->i_op->update_time)
141 +               inode->i_op->update_time(inode);
142 +       if (inode->i_op->write_time)
143 +               return inode->i_op->write_time(inode);
144         mark_inode_dirty_sync(inode);
145         return 0;
147 diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
148 index ec6dcdc..b69493d 100644
149 --- a/fs/xfs/xfs_iops.c
150 +++ b/fs/xfs/xfs_iops.c
151 @@ -983,42 +983,42 @@ xfs_vn_setattr(
152         return error;
155 -STATIC int
156 +STATIC void
157  xfs_vn_update_time(
158 -       struct inode            *inode,
159 -       struct timespec         *now,
160 -       int                     flags)
161 +       struct inode            *inode)
163 +       struct xfs_inode        *ip = XFS_I(inode);
165 +       trace_xfs_update_time(ip);
166 +       xfs_ilock(ip, XFS_ILOCK_EXCL);
167 +       ip->i_d.di_ctime.t_sec = (__int32_t) inode->i_ctime.tv_sec;
168 +       ip->i_d.di_ctime.t_nsec = (__int32_t) inode->i_ctime.tv_nsec;
170 +       ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
171 +       ip->i_d.di_mtime.t_nsec = (__int32_t) inode->i_mtime.tv_nsec;
173 +       ip->i_d.di_atime.t_sec = (__int32_t) inode->i_atime.tv_sec;
174 +       ip->i_d.di_atime.t_nsec = (__int32_t) inode->i_atime.tv_nsec;
175 +       xfs_iunlock(ip, XFS_ILOCK_EXCL);
178 +STATIC int
179 +xfs_vn_write_time(
180 +       struct inode            *inode)
182         struct xfs_inode        *ip = XFS_I(inode);
183         struct xfs_mount        *mp = ip->i_mount;
184         struct xfs_trans        *tp;
185         int                     error;
187 -       trace_xfs_update_time(ip);
189 +       trace_xfs_write_time(ip);
190         tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
191         error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
192         if (error) {
193                 xfs_trans_cancel(tp, 0);
194                 return error;
195         }
197         xfs_ilock(ip, XFS_ILOCK_EXCL);
198 -       if (flags & S_CTIME) {
199 -               inode->i_ctime = *now;
200 -               ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
201 -               ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
202 -       }
203 -       if (flags & S_MTIME) {
204 -               inode->i_mtime = *now;
205 -               ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
206 -               ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
207 -       }
208 -       if (flags & S_ATIME) {
209 -               inode->i_atime = *now;
210 -               ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
211 -               ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
212 -       }
213         xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
214         xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
215         return xfs_trans_commit(tp, 0);
216 @@ -1130,6 +1130,7 @@ static const struct inode_operations xfs_inode_operations = {
217         .listxattr              = xfs_vn_listxattr,
218         .fiemap                 = xfs_vn_fiemap,
219         .update_time            = xfs_vn_update_time,
220 +       .write_time             = xfs_vn_write_time,
221  };
223  static const struct inode_operations xfs_dir_inode_operations = {
224 @@ -1157,6 +1158,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
225         .removexattr            = generic_removexattr,
226         .listxattr              = xfs_vn_listxattr,
227         .update_time            = xfs_vn_update_time,
228 +       .write_time             = xfs_vn_write_time,
229         .tmpfile                = xfs_vn_tmpfile,
230  };
232 @@ -1185,6 +1187,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
233         .removexattr            = generic_removexattr,
234         .listxattr              = xfs_vn_listxattr,
235         .update_time            = xfs_vn_update_time,
236 +       .write_time             = xfs_vn_write_time,
237         .tmpfile                = xfs_vn_tmpfile,
238  };
240 @@ -1199,6 +1202,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
241         .removexattr            = generic_removexattr,
242         .listxattr              = xfs_vn_listxattr,
243         .update_time            = xfs_vn_update_time,
244 +       .write_time             = xfs_vn_write_time,
245  };
247  STATIC void
248 diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
249 index 51372e3..09d261c 100644
250 --- a/fs/xfs/xfs_trace.h
251 +++ b/fs/xfs/xfs_trace.h
252 @@ -677,6 +677,7 @@ DEFINE_INODE_EVENT(xfs_file_fsync);
253  DEFINE_INODE_EVENT(xfs_destroy_inode);
254  DEFINE_INODE_EVENT(xfs_evict_inode);
255  DEFINE_INODE_EVENT(xfs_update_time);
256 +DEFINE_INODE_EVENT(xfs_write_time);
258  DEFINE_INODE_EVENT(xfs_dquot_dqalloc);
259  DEFINE_INODE_EVENT(xfs_dquot_dqdetach);
260 diff --git a/include/linux/fs.h b/include/linux/fs.h
261 index f4b0ecd..befd5d2 100644
262 --- a/include/linux/fs.h
263 +++ b/include/linux/fs.h
264 @@ -1545,7 +1545,8 @@ struct inode_operations {
265         int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
266                       u64 len);
267         int (*is_readonly)(struct inode *);
268 -       int (*update_time)(struct inode *, struct timespec *, int);
269 +       void (*update_time)(struct inode *);
270 +       int (*write_time)(struct inode *);
271         int (*atomic_open)(struct inode *, struct dentry *,
272                            struct file *, unsigned open_flag,
273                            umode_t create_mode, int *opened);