V4 version of the lazytime patches
[ext4-patch-queue.git] / split-update_time-into-update_time-and-write_time
blob0638dba21826f51e48f8b2252a7609fe944fedce
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>
12 Cc: xfs@oss.sgi.com
13 Cc: linux-btrfs@vger.kernel.org
14 ---
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
35  removexattr:   yes
36  fiemap:                no
37  update_time:   no
38 +write_time:    no
39  atomic_open:   yes
40  tmpfile:       no
41  dentry_open:   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;
48         if (flags & S_ATIME)
49                 inode->i_atime = *now;
50 +       return 0;
53 +static int btrfs_write_time(struct inode *inode)
55         return btrfs_dirty_inode(inode);
56  }
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,
64  };
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,
71  };
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,
79  };
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,
87  };
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,
95  };
97  const struct dentry_operations btrfs_dentry_operations = {
98 diff --git a/fs/inode.c b/fs/inode.c
99 index 26753ba..8f5c4b5 100644
100 --- a/fs/inode.c
101 +++ b/fs/inode.c
102 @@ -1499,17 +1499,24 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
103   */
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;
117 +       int ret;
119 +       if (inode->i_op->update_time) {
120 +               ret = inode->i_op->update_time(inode, time, flags);
121 +               if (ret)
122 +                       return ret;
123 +       } else {
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;
132 +       }
133 +       if (inode->i_op->write_time)
134 +               return inode->i_op->write_time(inode);
135         mark_inode_dirty_sync(inode);
136         return 0;
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(
145  STATIC int
146 -xfs_vn_update_time(
147 -       struct inode            *inode,
148 -       struct timespec         *now,
149 -       int                     flags)
150 +xfs_vn_write_time(
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(
156         }
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;
163 -       }
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;
168 -       }
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;
173 -       }
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,
193  };
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,
203  };
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,
212  };
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,
220  };
222  STATIC void
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,
229                       u64 len);
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);