aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 19:12:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 19:12:34 -0500
commit038911597e17017cee55fe93d521164a27056866 (patch)
tree8f279a91de8237ce370a14d745940cccfd78ea07 /fs/ext4/inode.c
parent66dc830d14a222c9214a8557e9feb1e4a67a3857 (diff)
parenta26f49926da938f47561f386be56a83dd37a496d (diff)
Merge branch 'lazytime' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull lazytime mount option support from Al Viro: "Lazytime stuff from tytso" * 'lazytime' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: ext4: add optimization for the lazytime mount option vfs: add find_inode_nowait() function vfs: add support for a lazytime mount option
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 28555f191b62..85404f15e53a 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4174,6 +4174,65 @@ static int ext4_inode_blocks_set(handle_t *handle,
4174 return 0; 4174 return 0;
4175} 4175}
4176 4176
4177struct other_inode {
4178 unsigned long orig_ino;
4179 struct ext4_inode *raw_inode;
4180};
4181
4182static int other_inode_match(struct inode * inode, unsigned long ino,
4183 void *data)
4184{
4185 struct other_inode *oi = (struct other_inode *) data;
4186
4187 if ((inode->i_ino != ino) ||
4188 (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
4189 I_DIRTY_SYNC | I_DIRTY_DATASYNC)) ||
4190 ((inode->i_state & I_DIRTY_TIME) == 0))
4191 return 0;
4192 spin_lock(&inode->i_lock);
4193 if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
4194 I_DIRTY_SYNC | I_DIRTY_DATASYNC)) == 0) &&
4195 (inode->i_state & I_DIRTY_TIME)) {
4196 struct ext4_inode_info *ei = EXT4_I(inode);
4197
4198 inode->i_state &= ~(I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED);
4199 spin_unlock(&inode->i_lock);
4200
4201 spin_lock(&ei->i_raw_lock);
4202 EXT4_INODE_SET_XTIME(i_ctime, inode, oi->raw_inode);
4203 EXT4_INODE_SET_XTIME(i_mtime, inode, oi->raw_inode);
4204 EXT4_INODE_SET_XTIME(i_atime, inode, oi->raw_inode);
4205 ext4_inode_csum_set(inode, oi->raw_inode, ei);
4206 spin_unlock(&ei->i_raw_lock);
4207 trace_ext4_other_inode_update_time(inode, oi->orig_ino);
4208 return -1;
4209 }
4210 spin_unlock(&inode->i_lock);
4211 return -1;
4212}
4213
4214/*
4215 * Opportunistically update the other time fields for other inodes in
4216 * the same inode table block.
4217 */
4218static void ext4_update_other_inodes_time(struct super_block *sb,
4219 unsigned long orig_ino, char *buf)
4220{
4221 struct other_inode oi;
4222 unsigned long ino;
4223 int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
4224 int inode_size = EXT4_INODE_SIZE(sb);
4225
4226 oi.orig_ino = orig_ino;
4227 ino = orig_ino & ~(inodes_per_block - 1);
4228 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) {
4229 if (ino == orig_ino)
4230 continue;
4231 oi.raw_inode = (struct ext4_inode *) buf;
4232 (void) find_inode_nowait(sb, ino, other_inode_match, &oi);
4233 }
4234}
4235
4177/* 4236/*
4178 * Post the struct inode info into an on-disk inode location in the 4237 * Post the struct inode info into an on-disk inode location in the
4179 * buffer-cache. This gobbles the caller's reference to the 4238 * buffer-cache. This gobbles the caller's reference to the
@@ -4283,10 +4342,11 @@ static int ext4_do_update_inode(handle_t *handle,
4283 cpu_to_le16(ei->i_extra_isize); 4342 cpu_to_le16(ei->i_extra_isize);
4284 } 4343 }
4285 } 4344 }
4286
4287 ext4_inode_csum_set(inode, raw_inode, ei); 4345 ext4_inode_csum_set(inode, raw_inode, ei);
4288
4289 spin_unlock(&ei->i_raw_lock); 4346 spin_unlock(&ei->i_raw_lock);
4347 if (inode->i_sb->s_flags & MS_LAZYTIME)
4348 ext4_update_other_inodes_time(inode->i_sb, inode->i_ino,
4349 bh->b_data);
4290 4350
4291 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); 4351 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
4292 rc = ext4_handle_dirty_metadata(handle, NULL, bh); 4352 rc = ext4_handle_dirty_metadata(handle, NULL, bh);
@@ -4875,11 +4935,17 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
4875 * If the inode is marked synchronous, we don't honour that here - doing 4935 * If the inode is marked synchronous, we don't honour that here - doing
4876 * so would cause a commit on atime updates, which we don't bother doing. 4936 * so would cause a commit on atime updates, which we don't bother doing.
4877 * We handle synchronous inodes at the highest possible level. 4937 * We handle synchronous inodes at the highest possible level.
4938 *
4939 * If only the I_DIRTY_TIME flag is set, we can skip everything. If
4940 * I_DIRTY_TIME and I_DIRTY_SYNC is set, the only inode fields we need
4941 * to copy into the on-disk inode structure are the timestamp files.
4878 */ 4942 */
4879void ext4_dirty_inode(struct inode *inode, int flags) 4943void ext4_dirty_inode(struct inode *inode, int flags)
4880{ 4944{
4881 handle_t *handle; 4945 handle_t *handle;
4882 4946
4947 if (flags == I_DIRTY_TIME)
4948 return;
4883 handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); 4949 handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
4884 if (IS_ERR(handle)) 4950 if (IS_ERR(handle))
4885 goto out; 4951 goto out;