aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c70
-rw-r--r--fs/ext4/super.c10
-rw-r--r--fs/fs-writeback.c62
-rw-r--r--fs/gfs2/file.c4
-rw-r--r--fs/inode.c106
-rw-r--r--fs/jfs/file.c2
-rw-r--r--fs/libfs.c2
-rw-r--r--fs/proc_namespace.c1
-rw-r--r--fs/sync.c8
-rw-r--r--include/linux/backing-dev.h1
-rw-r--r--include/linux/fs.h10
-rw-r--r--include/trace/events/ext4.h30
-rw-r--r--include/trace/events/writeback.h60
-rw-r--r--include/uapi/linux/fs.h4
-rw-r--r--mm/backing-dev.c10
15 files changed, 343 insertions, 37 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;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 10e8c6b7ca08..1adac6868e6f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1126,6 +1126,7 @@ enum {
1126 Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, 1126 Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
1127 Opt_usrquota, Opt_grpquota, Opt_i_version, Opt_dax, 1127 Opt_usrquota, Opt_grpquota, Opt_i_version, Opt_dax,
1128 Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, 1128 Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
1129 Opt_lazytime, Opt_nolazytime,
1129 Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, 1130 Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
1130 Opt_inode_readahead_blks, Opt_journal_ioprio, 1131 Opt_inode_readahead_blks, Opt_journal_ioprio,
1131 Opt_dioread_nolock, Opt_dioread_lock, 1132 Opt_dioread_nolock, Opt_dioread_lock,
@@ -1190,6 +1191,8 @@ static const match_table_t tokens = {
1190 {Opt_dax, "dax"}, 1191 {Opt_dax, "dax"},
1191 {Opt_stripe, "stripe=%u"}, 1192 {Opt_stripe, "stripe=%u"},
1192 {Opt_delalloc, "delalloc"}, 1193 {Opt_delalloc, "delalloc"},
1194 {Opt_lazytime, "lazytime"},
1195 {Opt_nolazytime, "nolazytime"},
1193 {Opt_nodelalloc, "nodelalloc"}, 1196 {Opt_nodelalloc, "nodelalloc"},
1194 {Opt_removed, "mblk_io_submit"}, 1197 {Opt_removed, "mblk_io_submit"},
1195 {Opt_removed, "nomblk_io_submit"}, 1198 {Opt_removed, "nomblk_io_submit"},
@@ -1448,6 +1451,12 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
1448 case Opt_i_version: 1451 case Opt_i_version:
1449 sb->s_flags |= MS_I_VERSION; 1452 sb->s_flags |= MS_I_VERSION;
1450 return 1; 1453 return 1;
1454 case Opt_lazytime:
1455 sb->s_flags |= MS_LAZYTIME;
1456 return 1;
1457 case Opt_nolazytime:
1458 sb->s_flags &= ~MS_LAZYTIME;
1459 return 1;
1451 } 1460 }
1452 1461
1453 for (m = ext4_mount_opts; m->token != Opt_err; m++) 1462 for (m = ext4_mount_opts; m->token != Opt_err; m++)
@@ -5044,6 +5053,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
5044 } 5053 }
5045#endif 5054#endif
5046 5055
5056 *flags = (*flags & ~MS_LAZYTIME) | (sb->s_flags & MS_LAZYTIME);
5047 ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data); 5057 ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
5048 kfree(orig_data); 5058 kfree(orig_data);
5049 return 0; 5059 return 0;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c399152de397..073657f755d4 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -253,14 +253,19 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t)
253 return ret; 253 return ret;
254} 254}
255 255
256#define EXPIRE_DIRTY_ATIME 0x0001
257
256/* 258/*
257 * Move expired (dirtied before work->older_than_this) dirty inodes from 259 * Move expired (dirtied before work->older_than_this) dirty inodes from
258 * @delaying_queue to @dispatch_queue. 260 * @delaying_queue to @dispatch_queue.
259 */ 261 */
260static int move_expired_inodes(struct list_head *delaying_queue, 262static int move_expired_inodes(struct list_head *delaying_queue,
261 struct list_head *dispatch_queue, 263 struct list_head *dispatch_queue,
264 int flags,
262 struct wb_writeback_work *work) 265 struct wb_writeback_work *work)
263{ 266{
267 unsigned long *older_than_this = NULL;
268 unsigned long expire_time;
264 LIST_HEAD(tmp); 269 LIST_HEAD(tmp);
265 struct list_head *pos, *node; 270 struct list_head *pos, *node;
266 struct super_block *sb = NULL; 271 struct super_block *sb = NULL;
@@ -268,13 +273,21 @@ static int move_expired_inodes(struct list_head *delaying_queue,
268 int do_sb_sort = 0; 273 int do_sb_sort = 0;
269 int moved = 0; 274 int moved = 0;
270 275
276 if ((flags & EXPIRE_DIRTY_ATIME) == 0)
277 older_than_this = work->older_than_this;
278 else if ((work->reason == WB_REASON_SYNC) == 0) {
279 expire_time = jiffies - (HZ * 86400);
280 older_than_this = &expire_time;
281 }
271 while (!list_empty(delaying_queue)) { 282 while (!list_empty(delaying_queue)) {
272 inode = wb_inode(delaying_queue->prev); 283 inode = wb_inode(delaying_queue->prev);
273 if (work->older_than_this && 284 if (older_than_this &&
274 inode_dirtied_after(inode, *work->older_than_this)) 285 inode_dirtied_after(inode, *older_than_this))
275 break; 286 break;
276 list_move(&inode->i_wb_list, &tmp); 287 list_move(&inode->i_wb_list, &tmp);
277 moved++; 288 moved++;
289 if (flags & EXPIRE_DIRTY_ATIME)
290 set_bit(__I_DIRTY_TIME_EXPIRED, &inode->i_state);
278 if (sb_is_blkdev_sb(inode->i_sb)) 291 if (sb_is_blkdev_sb(inode->i_sb))
279 continue; 292 continue;
280 if (sb && sb != inode->i_sb) 293 if (sb && sb != inode->i_sb)
@@ -315,9 +328,12 @@ out:
315static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work) 328static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work)
316{ 329{
317 int moved; 330 int moved;
331
318 assert_spin_locked(&wb->list_lock); 332 assert_spin_locked(&wb->list_lock);
319 list_splice_init(&wb->b_more_io, &wb->b_io); 333 list_splice_init(&wb->b_more_io, &wb->b_io);
320 moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, work); 334 moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, work);
335 moved += move_expired_inodes(&wb->b_dirty_time, &wb->b_io,
336 EXPIRE_DIRTY_ATIME, work);
321 trace_writeback_queue_io(wb, work, moved); 337 trace_writeback_queue_io(wb, work, moved);
322} 338}
323 339
@@ -441,6 +457,8 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
441 * updates after data IO completion. 457 * updates after data IO completion.
442 */ 458 */
443 redirty_tail(inode, wb); 459 redirty_tail(inode, wb);
460 } else if (inode->i_state & I_DIRTY_TIME) {
461 list_move(&inode->i_wb_list, &wb->b_dirty_time);
444 } else { 462 } else {
445 /* The inode is clean. Remove from writeback lists. */ 463 /* The inode is clean. Remove from writeback lists. */
446 list_del_init(&inode->i_wb_list); 464 list_del_init(&inode->i_wb_list);
@@ -487,7 +505,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
487 spin_lock(&inode->i_lock); 505 spin_lock(&inode->i_lock);
488 506
489 dirty = inode->i_state & I_DIRTY; 507 dirty = inode->i_state & I_DIRTY;
490 inode->i_state &= ~I_DIRTY; 508 if (((dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) &&
509 (inode->i_state & I_DIRTY_TIME)) ||
510 (inode->i_state & I_DIRTY_TIME_EXPIRED)) {
511 dirty |= I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED;
512 trace_writeback_lazytime(inode);
513 }
514 inode->i_state &= ~dirty;
491 515
492 /* 516 /*
493 * Paired with smp_mb() in __mark_inode_dirty(). This allows 517 * Paired with smp_mb() in __mark_inode_dirty(). This allows
@@ -507,8 +531,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
507 531
508 spin_unlock(&inode->i_lock); 532 spin_unlock(&inode->i_lock);
509 533
534 if (dirty & I_DIRTY_TIME)
535 mark_inode_dirty_sync(inode);
510 /* Don't write the inode if only I_DIRTY_PAGES was set */ 536 /* Don't write the inode if only I_DIRTY_PAGES was set */
511 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { 537 if (dirty & ~I_DIRTY_PAGES) {
512 int err = write_inode(inode, wbc); 538 int err = write_inode(inode, wbc);
513 if (ret == 0) 539 if (ret == 0)
514 ret = err; 540 ret = err;
@@ -556,7 +582,7 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
556 * make sure inode is on some writeback list and leave it there unless 582 * make sure inode is on some writeback list and leave it there unless
557 * we have completely cleaned the inode. 583 * we have completely cleaned the inode.
558 */ 584 */
559 if (!(inode->i_state & I_DIRTY) && 585 if (!(inode->i_state & I_DIRTY_ALL) &&
560 (wbc->sync_mode != WB_SYNC_ALL || 586 (wbc->sync_mode != WB_SYNC_ALL ||
561 !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK))) 587 !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK)))
562 goto out; 588 goto out;
@@ -571,7 +597,7 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
571 * If inode is clean, remove it from writeback lists. Otherwise don't 597 * If inode is clean, remove it from writeback lists. Otherwise don't
572 * touch it. See comment above for explanation. 598 * touch it. See comment above for explanation.
573 */ 599 */
574 if (!(inode->i_state & I_DIRTY)) 600 if (!(inode->i_state & I_DIRTY_ALL))
575 list_del_init(&inode->i_wb_list); 601 list_del_init(&inode->i_wb_list);
576 spin_unlock(&wb->list_lock); 602 spin_unlock(&wb->list_lock);
577 inode_sync_complete(inode); 603 inode_sync_complete(inode);
@@ -713,7 +739,7 @@ static long writeback_sb_inodes(struct super_block *sb,
713 wrote += write_chunk - wbc.nr_to_write; 739 wrote += write_chunk - wbc.nr_to_write;
714 spin_lock(&wb->list_lock); 740 spin_lock(&wb->list_lock);
715 spin_lock(&inode->i_lock); 741 spin_lock(&inode->i_lock);
716 if (!(inode->i_state & I_DIRTY)) 742 if (!(inode->i_state & I_DIRTY_ALL))
717 wrote++; 743 wrote++;
718 requeue_inode(inode, wb, &wbc); 744 requeue_inode(inode, wb, &wbc);
719 inode_sync_complete(inode); 745 inode_sync_complete(inode);
@@ -1151,16 +1177,20 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
1151 * page->mapping->host, so the page-dirtying time is recorded in the internal 1177 * page->mapping->host, so the page-dirtying time is recorded in the internal
1152 * blockdev inode. 1178 * blockdev inode.
1153 */ 1179 */
1180#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
1154void __mark_inode_dirty(struct inode *inode, int flags) 1181void __mark_inode_dirty(struct inode *inode, int flags)
1155{ 1182{
1156 struct super_block *sb = inode->i_sb; 1183 struct super_block *sb = inode->i_sb;
1157 struct backing_dev_info *bdi = NULL; 1184 struct backing_dev_info *bdi = NULL;
1185 int dirtytime;
1186
1187 trace_writeback_mark_inode_dirty(inode, flags);
1158 1188
1159 /* 1189 /*
1160 * Don't do this for I_DIRTY_PAGES - that doesn't actually 1190 * Don't do this for I_DIRTY_PAGES - that doesn't actually
1161 * dirty the inode itself 1191 * dirty the inode itself
1162 */ 1192 */
1163 if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { 1193 if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_TIME)) {
1164 trace_writeback_dirty_inode_start(inode, flags); 1194 trace_writeback_dirty_inode_start(inode, flags);
1165 1195
1166 if (sb->s_op->dirty_inode) 1196 if (sb->s_op->dirty_inode)
@@ -1168,6 +1198,9 @@ void __mark_inode_dirty(struct inode *inode, int flags)
1168 1198
1169 trace_writeback_dirty_inode(inode, flags); 1199 trace_writeback_dirty_inode(inode, flags);
1170 } 1200 }
1201 if (flags & I_DIRTY_INODE)
1202 flags &= ~I_DIRTY_TIME;
1203 dirtytime = flags & I_DIRTY_TIME;
1171 1204
1172 /* 1205 /*
1173 * Paired with smp_mb() in __writeback_single_inode() for the 1206 * Paired with smp_mb() in __writeback_single_inode() for the
@@ -1175,16 +1208,21 @@ void __mark_inode_dirty(struct inode *inode, int flags)
1175 */ 1208 */
1176 smp_mb(); 1209 smp_mb();
1177 1210
1178 if ((inode->i_state & flags) == flags) 1211 if (((inode->i_state & flags) == flags) ||
1212 (dirtytime && (inode->i_state & I_DIRTY_INODE)))
1179 return; 1213 return;
1180 1214
1181 if (unlikely(block_dump)) 1215 if (unlikely(block_dump))
1182 block_dump___mark_inode_dirty(inode); 1216 block_dump___mark_inode_dirty(inode);
1183 1217
1184 spin_lock(&inode->i_lock); 1218 spin_lock(&inode->i_lock);
1219 if (dirtytime && (inode->i_state & I_DIRTY_INODE))
1220 goto out_unlock_inode;
1185 if ((inode->i_state & flags) != flags) { 1221 if ((inode->i_state & flags) != flags) {
1186 const int was_dirty = inode->i_state & I_DIRTY; 1222 const int was_dirty = inode->i_state & I_DIRTY;
1187 1223
1224 if (flags & I_DIRTY_INODE)
1225 inode->i_state &= ~I_DIRTY_TIME;
1188 inode->i_state |= flags; 1226 inode->i_state |= flags;
1189 1227
1190 /* 1228 /*
@@ -1231,8 +1269,10 @@ void __mark_inode_dirty(struct inode *inode, int flags)
1231 } 1269 }
1232 1270
1233 inode->dirtied_when = jiffies; 1271 inode->dirtied_when = jiffies;
1234 list_move(&inode->i_wb_list, &bdi->wb.b_dirty); 1272 list_move(&inode->i_wb_list, dirtytime ?
1273 &bdi->wb.b_dirty_time : &bdi->wb.b_dirty);
1235 spin_unlock(&bdi->wb.list_lock); 1274 spin_unlock(&bdi->wb.list_lock);
1275 trace_writeback_dirty_inode_enqueue(inode);
1236 1276
1237 if (wakeup_bdi) 1277 if (wakeup_bdi)
1238 bdi_wakeup_thread_delayed(bdi); 1278 bdi_wakeup_thread_delayed(bdi);
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index ec9c2d33477a..3e32bb8e2d7e 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -654,7 +654,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
654{ 654{
655 struct address_space *mapping = file->f_mapping; 655 struct address_space *mapping = file->f_mapping;
656 struct inode *inode = mapping->host; 656 struct inode *inode = mapping->host;
657 int sync_state = inode->i_state & I_DIRTY; 657 int sync_state = inode->i_state & I_DIRTY_ALL;
658 struct gfs2_inode *ip = GFS2_I(inode); 658 struct gfs2_inode *ip = GFS2_I(inode);
659 int ret = 0, ret1 = 0; 659 int ret = 0, ret1 = 0;
660 660
@@ -667,7 +667,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
667 if (!gfs2_is_jdata(ip)) 667 if (!gfs2_is_jdata(ip))
668 sync_state &= ~I_DIRTY_PAGES; 668 sync_state &= ~I_DIRTY_PAGES;
669 if (datasync) 669 if (datasync)
670 sync_state &= ~I_DIRTY_SYNC; 670 sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
671 671
672 if (sync_state) { 672 if (sync_state) {
673 ret = sync_inode_metadata(inode, 1); 673 ret = sync_inode_metadata(inode, 1);
diff --git a/fs/inode.c b/fs/inode.c
index 86bfaca724db..f00b16f45507 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -18,6 +18,7 @@
18#include <linux/buffer_head.h> /* for inode_has_buffers */ 18#include <linux/buffer_head.h> /* for inode_has_buffers */
19#include <linux/ratelimit.h> 19#include <linux/ratelimit.h>
20#include <linux/list_lru.h> 20#include <linux/list_lru.h>
21#include <trace/events/writeback.h>
21#include "internal.h" 22#include "internal.h"
22 23
23/* 24/*
@@ -30,7 +31,7 @@
30 * inode_sb_list_lock protects: 31 * inode_sb_list_lock protects:
31 * sb->s_inodes, inode->i_sb_list 32 * sb->s_inodes, inode->i_sb_list
32 * bdi->wb.list_lock protects: 33 * bdi->wb.list_lock protects:
33 * bdi->wb.b_{dirty,io,more_io}, inode->i_wb_list 34 * bdi->wb.b_{dirty,io,more_io,dirty_time}, inode->i_wb_list
34 * inode_hash_lock protects: 35 * inode_hash_lock protects:
35 * inode_hashtable, inode->i_hash 36 * inode_hashtable, inode->i_hash
36 * 37 *
@@ -403,7 +404,8 @@ static void inode_lru_list_add(struct inode *inode)
403 */ 404 */
404void inode_add_lru(struct inode *inode) 405void inode_add_lru(struct inode *inode)
405{ 406{
406 if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) && 407 if (!(inode->i_state & (I_DIRTY_ALL | I_SYNC |
408 I_FREEING | I_WILL_FREE)) &&
407 !atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE) 409 !atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE)
408 inode_lru_list_add(inode); 410 inode_lru_list_add(inode);
409} 411}
@@ -634,7 +636,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
634 spin_unlock(&inode->i_lock); 636 spin_unlock(&inode->i_lock);
635 continue; 637 continue;
636 } 638 }
637 if (inode->i_state & I_DIRTY && !kill_dirty) { 639 if (inode->i_state & I_DIRTY_ALL && !kill_dirty) {
638 spin_unlock(&inode->i_lock); 640 spin_unlock(&inode->i_lock);
639 busy = 1; 641 busy = 1;
640 continue; 642 continue;
@@ -1268,6 +1270,56 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
1268} 1270}
1269EXPORT_SYMBOL(ilookup); 1271EXPORT_SYMBOL(ilookup);
1270 1272
1273/**
1274 * find_inode_nowait - find an inode in the inode cache
1275 * @sb: super block of file system to search
1276 * @hashval: hash value (usually inode number) to search for
1277 * @match: callback used for comparisons between inodes
1278 * @data: opaque data pointer to pass to @match
1279 *
1280 * Search for the inode specified by @hashval and @data in the inode
1281 * cache, where the helper function @match will return 0 if the inode
1282 * does not match, 1 if the inode does match, and -1 if the search
1283 * should be stopped. The @match function must be responsible for
1284 * taking the i_lock spin_lock and checking i_state for an inode being
1285 * freed or being initialized, and incrementing the reference count
1286 * before returning 1. It also must not sleep, since it is called with
1287 * the inode_hash_lock spinlock held.
1288 *
1289 * This is a even more generalized version of ilookup5() when the
1290 * function must never block --- find_inode() can block in
1291 * __wait_on_freeing_inode() --- or when the caller can not increment
1292 * the reference count because the resulting iput() might cause an
1293 * inode eviction. The tradeoff is that the @match funtion must be
1294 * very carefully implemented.
1295 */
1296struct inode *find_inode_nowait(struct super_block *sb,
1297 unsigned long hashval,
1298 int (*match)(struct inode *, unsigned long,
1299 void *),
1300 void *data)
1301{
1302 struct hlist_head *head = inode_hashtable + hash(sb, hashval);
1303 struct inode *inode, *ret_inode = NULL;
1304 int mval;
1305
1306 spin_lock(&inode_hash_lock);
1307 hlist_for_each_entry(inode, head, i_hash) {
1308 if (inode->i_sb != sb)
1309 continue;
1310 mval = match(inode, hashval, data);
1311 if (mval == 0)
1312 continue;
1313 if (mval == 1)
1314 ret_inode = inode;
1315 goto out;
1316 }
1317out:
1318 spin_unlock(&inode_hash_lock);
1319 return ret_inode;
1320}
1321EXPORT_SYMBOL(find_inode_nowait);
1322
1271int insert_inode_locked(struct inode *inode) 1323int insert_inode_locked(struct inode *inode)
1272{ 1324{
1273 struct super_block *sb = inode->i_sb; 1325 struct super_block *sb = inode->i_sb;
@@ -1418,11 +1470,20 @@ static void iput_final(struct inode *inode)
1418 */ 1470 */
1419void iput(struct inode *inode) 1471void iput(struct inode *inode)
1420{ 1472{
1421 if (inode) { 1473 if (!inode)
1422 BUG_ON(inode->i_state & I_CLEAR); 1474 return;
1423 1475 BUG_ON(inode->i_state & I_CLEAR);
1424 if (atomic_dec_and_lock(&inode->i_count, &inode->i_lock)) 1476retry:
1425 iput_final(inode); 1477 if (atomic_dec_and_lock(&inode->i_count, &inode->i_lock)) {
1478 if (inode->i_nlink && (inode->i_state & I_DIRTY_TIME)) {
1479 atomic_inc(&inode->i_count);
1480 inode->i_state &= ~I_DIRTY_TIME;
1481 spin_unlock(&inode->i_lock);
1482 trace_writeback_lazytime_iput(inode);
1483 mark_inode_dirty_sync(inode);
1484 goto retry;
1485 }
1486 iput_final(inode);
1426 } 1487 }
1427} 1488}
1428EXPORT_SYMBOL(iput); 1489EXPORT_SYMBOL(iput);
@@ -1481,14 +1542,9 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
1481 return 0; 1542 return 0;
1482} 1543}
1483 1544
1484/* 1545int generic_update_time(struct inode *inode, struct timespec *time, int flags)
1485 * This does the actual work of updating an inodes time or version. Must have
1486 * had called mnt_want_write() before calling this.
1487 */
1488static int update_time(struct inode *inode, struct timespec *time, int flags)
1489{ 1546{
1490 if (inode->i_op->update_time) 1547 int iflags = I_DIRTY_TIME;
1491 return inode->i_op->update_time(inode, time, flags);
1492 1548
1493 if (flags & S_ATIME) 1549 if (flags & S_ATIME)
1494 inode->i_atime = *time; 1550 inode->i_atime = *time;
@@ -1498,9 +1554,27 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
1498 inode->i_ctime = *time; 1554 inode->i_ctime = *time;
1499 if (flags & S_MTIME) 1555 if (flags & S_MTIME)
1500 inode->i_mtime = *time; 1556 inode->i_mtime = *time;
1501 mark_inode_dirty_sync(inode); 1557
1558 if (!(inode->i_sb->s_flags & MS_LAZYTIME) || (flags & S_VERSION))
1559 iflags |= I_DIRTY_SYNC;
1560 __mark_inode_dirty(inode, iflags);
1502 return 0; 1561 return 0;
1503} 1562}
1563EXPORT_SYMBOL(generic_update_time);
1564
1565/*
1566 * This does the actual work of updating an inodes time or version. Must have
1567 * had called mnt_want_write() before calling this.
1568 */
1569static int update_time(struct inode *inode, struct timespec *time, int flags)
1570{
1571 int (*update_time)(struct inode *, struct timespec *, int);
1572
1573 update_time = inode->i_op->update_time ? inode->i_op->update_time :
1574 generic_update_time;
1575
1576 return update_time(inode, time, flags);
1577}
1504 1578
1505/** 1579/**
1506 * touch_atime - update the access time 1580 * touch_atime - update the access time
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 33aa0cc1f8b8..10815f8dfd8b 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -39,7 +39,7 @@ int jfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
39 return rc; 39 return rc;
40 40
41 mutex_lock(&inode->i_mutex); 41 mutex_lock(&inode->i_mutex);
42 if (!(inode->i_state & I_DIRTY) || 42 if (!(inode->i_state & I_DIRTY_ALL) ||
43 (datasync && !(inode->i_state & I_DIRTY_DATASYNC))) { 43 (datasync && !(inode->i_state & I_DIRTY_DATASYNC))) {
44 /* Make sure committed changes hit the disk */ 44 /* Make sure committed changes hit the disk */
45 jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1); 45 jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1);
diff --git a/fs/libfs.c b/fs/libfs.c
index 005843ce5dbd..b2ffdb045be4 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -948,7 +948,7 @@ int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
948 948
949 mutex_lock(&inode->i_mutex); 949 mutex_lock(&inode->i_mutex);
950 ret = sync_mapping_buffers(inode->i_mapping); 950 ret = sync_mapping_buffers(inode->i_mapping);
951 if (!(inode->i_state & I_DIRTY)) 951 if (!(inode->i_state & I_DIRTY_ALL))
952 goto out; 952 goto out;
953 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 953 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
954 goto out; 954 goto out;
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 0f96f71ab32b..8db932da4009 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -44,6 +44,7 @@ static int show_sb_opts(struct seq_file *m, struct super_block *sb)
44 { MS_SYNCHRONOUS, ",sync" }, 44 { MS_SYNCHRONOUS, ",sync" },
45 { MS_DIRSYNC, ",dirsync" }, 45 { MS_DIRSYNC, ",dirsync" },
46 { MS_MANDLOCK, ",mand" }, 46 { MS_MANDLOCK, ",mand" },
47 { MS_LAZYTIME, ",lazytime" },
47 { 0, NULL } 48 { 0, NULL }
48 }; 49 };
49 const struct proc_fs_info *fs_infop; 50 const struct proc_fs_info *fs_infop;
diff --git a/fs/sync.c b/fs/sync.c
index 01d9f18a70b5..fbc98ee62044 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -177,8 +177,16 @@ SYSCALL_DEFINE1(syncfs, int, fd)
177 */ 177 */
178int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) 178int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
179{ 179{
180 struct inode *inode = file->f_mapping->host;
181
180 if (!file->f_op->fsync) 182 if (!file->f_op->fsync)
181 return -EINVAL; 183 return -EINVAL;
184 if (!datasync && (inode->i_state & I_DIRTY_TIME)) {
185 spin_lock(&inode->i_lock);
186 inode->i_state &= ~I_DIRTY_TIME;
187 spin_unlock(&inode->i_lock);
188 mark_inode_dirty_sync(inode);
189 }
182 return file->f_op->fsync(file, start, end, datasync); 190 return file->f_op->fsync(file, start, end, datasync);
183} 191}
184EXPORT_SYMBOL(vfs_fsync_range); 192EXPORT_SYMBOL(vfs_fsync_range);
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index d94077fea1f8..aff923ae8c4b 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -55,6 +55,7 @@ struct bdi_writeback {
55 struct list_head b_dirty; /* dirty inodes */ 55 struct list_head b_dirty; /* dirty inodes */
56 struct list_head b_io; /* parked for writeback */ 56 struct list_head b_io; /* parked for writeback */
57 struct list_head b_more_io; /* parked for more writeback */ 57 struct list_head b_more_io; /* parked for more writeback */
58 struct list_head b_dirty_time; /* time stamps are dirty */
58 spinlock_t list_lock; /* protects the b_* lists */ 59 spinlock_t list_lock; /* protects the b_* lists */
59}; 60};
60 61
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0b5b146d0490..447932aed1e1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1790,8 +1790,12 @@ struct super_operations {
1790#define __I_DIO_WAKEUP 9 1790#define __I_DIO_WAKEUP 9
1791#define I_DIO_WAKEUP (1 << I_DIO_WAKEUP) 1791#define I_DIO_WAKEUP (1 << I_DIO_WAKEUP)
1792#define I_LINKABLE (1 << 10) 1792#define I_LINKABLE (1 << 10)
1793#define I_DIRTY_TIME (1 << 11)
1794#define __I_DIRTY_TIME_EXPIRED 12
1795#define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED)
1793 1796
1794#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) 1797#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
1798#define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
1795 1799
1796extern void __mark_inode_dirty(struct inode *, int); 1800extern void __mark_inode_dirty(struct inode *, int);
1797static inline void mark_inode_dirty(struct inode *inode) 1801static inline void mark_inode_dirty(struct inode *inode)
@@ -1954,6 +1958,7 @@ extern int current_umask(void);
1954 1958
1955extern void ihold(struct inode * inode); 1959extern void ihold(struct inode * inode);
1956extern void iput(struct inode *); 1960extern void iput(struct inode *);
1961extern int generic_update_time(struct inode *, struct timespec *, int);
1957 1962
1958static inline struct inode *file_inode(const struct file *f) 1963static inline struct inode *file_inode(const struct file *f)
1959{ 1964{
@@ -2492,6 +2497,11 @@ extern struct inode *ilookup(struct super_block *sb, unsigned long ino);
2492 2497
2493extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *); 2498extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *);
2494extern struct inode * iget_locked(struct super_block *, unsigned long); 2499extern struct inode * iget_locked(struct super_block *, unsigned long);
2500extern struct inode *find_inode_nowait(struct super_block *,
2501 unsigned long,
2502 int (*match)(struct inode *,
2503 unsigned long, void *),
2504 void *data);
2495extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *); 2505extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *);
2496extern int insert_inode_locked(struct inode *); 2506extern int insert_inode_locked(struct inode *);
2497#ifdef CONFIG_DEBUG_LOCK_ALLOC 2507#ifdef CONFIG_DEBUG_LOCK_ALLOC
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 6cfb841fea7c..6e5abd6d38a2 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -73,6 +73,36 @@ struct extent_status;
73 { FALLOC_FL_ZERO_RANGE, "ZERO_RANGE"}) 73 { FALLOC_FL_ZERO_RANGE, "ZERO_RANGE"})
74 74
75 75
76TRACE_EVENT(ext4_other_inode_update_time,
77 TP_PROTO(struct inode *inode, ino_t orig_ino),
78
79 TP_ARGS(inode, orig_ino),
80
81 TP_STRUCT__entry(
82 __field( dev_t, dev )
83 __field( ino_t, ino )
84 __field( ino_t, orig_ino )
85 __field( uid_t, uid )
86 __field( gid_t, gid )
87 __field( __u16, mode )
88 ),
89
90 TP_fast_assign(
91 __entry->orig_ino = orig_ino;
92 __entry->dev = inode->i_sb->s_dev;
93 __entry->ino = inode->i_ino;
94 __entry->uid = i_uid_read(inode);
95 __entry->gid = i_gid_read(inode);
96 __entry->mode = inode->i_mode;
97 ),
98
99 TP_printk("dev %d,%d orig_ino %lu ino %lu mode 0%o uid %u gid %u",
100 MAJOR(__entry->dev), MINOR(__entry->dev),
101 (unsigned long) __entry->orig_ino,
102 (unsigned long) __entry->ino, __entry->mode,
103 __entry->uid, __entry->gid)
104);
105
76TRACE_EVENT(ext4_free_inode, 106TRACE_EVENT(ext4_free_inode,
77 TP_PROTO(struct inode *inode), 107 TP_PROTO(struct inode *inode),
78 108
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
index 0e9310905413..5a14ead59696 100644
--- a/include/trace/events/writeback.h
+++ b/include/trace/events/writeback.h
@@ -18,6 +18,8 @@
18 {I_FREEING, "I_FREEING"}, \ 18 {I_FREEING, "I_FREEING"}, \
19 {I_CLEAR, "I_CLEAR"}, \ 19 {I_CLEAR, "I_CLEAR"}, \
20 {I_SYNC, "I_SYNC"}, \ 20 {I_SYNC, "I_SYNC"}, \
21 {I_DIRTY_TIME, "I_DIRTY_TIME"}, \
22 {I_DIRTY_TIME_EXPIRED, "I_DIRTY_TIME_EXPIRED"}, \
21 {I_REFERENCED, "I_REFERENCED"} \ 23 {I_REFERENCED, "I_REFERENCED"} \
22 ) 24 )
23 25
@@ -68,6 +70,7 @@ DECLARE_EVENT_CLASS(writeback_dirty_inode_template,
68 TP_STRUCT__entry ( 70 TP_STRUCT__entry (
69 __array(char, name, 32) 71 __array(char, name, 32)
70 __field(unsigned long, ino) 72 __field(unsigned long, ino)
73 __field(unsigned long, state)
71 __field(unsigned long, flags) 74 __field(unsigned long, flags)
72 ), 75 ),
73 76
@@ -78,16 +81,25 @@ DECLARE_EVENT_CLASS(writeback_dirty_inode_template,
78 strncpy(__entry->name, 81 strncpy(__entry->name,
79 bdi->dev ? dev_name(bdi->dev) : "(unknown)", 32); 82 bdi->dev ? dev_name(bdi->dev) : "(unknown)", 32);
80 __entry->ino = inode->i_ino; 83 __entry->ino = inode->i_ino;
84 __entry->state = inode->i_state;
81 __entry->flags = flags; 85 __entry->flags = flags;
82 ), 86 ),
83 87
84 TP_printk("bdi %s: ino=%lu flags=%s", 88 TP_printk("bdi %s: ino=%lu state=%s flags=%s",
85 __entry->name, 89 __entry->name,
86 __entry->ino, 90 __entry->ino,
91 show_inode_state(__entry->state),
87 show_inode_state(__entry->flags) 92 show_inode_state(__entry->flags)
88 ) 93 )
89); 94);
90 95
96DEFINE_EVENT(writeback_dirty_inode_template, writeback_mark_inode_dirty,
97
98 TP_PROTO(struct inode *inode, int flags),
99
100 TP_ARGS(inode, flags)
101);
102
91DEFINE_EVENT(writeback_dirty_inode_template, writeback_dirty_inode_start, 103DEFINE_EVENT(writeback_dirty_inode_template, writeback_dirty_inode_start,
92 104
93 TP_PROTO(struct inode *inode, int flags), 105 TP_PROTO(struct inode *inode, int flags),
@@ -596,6 +608,52 @@ DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode,
596 TP_ARGS(inode, wbc, nr_to_write) 608 TP_ARGS(inode, wbc, nr_to_write)
597); 609);
598 610
611DECLARE_EVENT_CLASS(writeback_lazytime_template,
612 TP_PROTO(struct inode *inode),
613
614 TP_ARGS(inode),
615
616 TP_STRUCT__entry(
617 __field( dev_t, dev )
618 __field(unsigned long, ino )
619 __field(unsigned long, state )
620 __field( __u16, mode )
621 __field(unsigned long, dirtied_when )
622 ),
623
624 TP_fast_assign(
625 __entry->dev = inode->i_sb->s_dev;
626 __entry->ino = inode->i_ino;
627 __entry->state = inode->i_state;
628 __entry->mode = inode->i_mode;
629 __entry->dirtied_when = inode->dirtied_when;
630 ),
631
632 TP_printk("dev %d,%d ino %lu dirtied %lu state %s mode 0%o",
633 MAJOR(__entry->dev), MINOR(__entry->dev),
634 __entry->ino, __entry->dirtied_when,
635 show_inode_state(__entry->state), __entry->mode)
636);
637
638DEFINE_EVENT(writeback_lazytime_template, writeback_lazytime,
639 TP_PROTO(struct inode *inode),
640
641 TP_ARGS(inode)
642);
643
644DEFINE_EVENT(writeback_lazytime_template, writeback_lazytime_iput,
645 TP_PROTO(struct inode *inode),
646
647 TP_ARGS(inode)
648);
649
650DEFINE_EVENT(writeback_lazytime_template, writeback_dirty_inode_enqueue,
651
652 TP_PROTO(struct inode *inode),
653
654 TP_ARGS(inode)
655);
656
599#endif /* _TRACE_WRITEBACK_H */ 657#endif /* _TRACE_WRITEBACK_H */
600 658
601/* This part must be outside protection */ 659/* This part must be outside protection */
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 3735fa0a6784..9b964a5920af 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -90,6 +90,7 @@ struct inodes_stat_t {
90#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ 90#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
91#define MS_I_VERSION (1<<23) /* Update inode I_version field */ 91#define MS_I_VERSION (1<<23) /* Update inode I_version field */
92#define MS_STRICTATIME (1<<24) /* Always perform atime updates */ 92#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
93#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
93 94
94/* These sb flags are internal to the kernel */ 95/* These sb flags are internal to the kernel */
95#define MS_NOSEC (1<<28) 96#define MS_NOSEC (1<<28)
@@ -100,7 +101,8 @@ struct inodes_stat_t {
100/* 101/*
101 * Superblock flags that can be altered by MS_REMOUNT 102 * Superblock flags that can be altered by MS_REMOUNT
102 */ 103 */
103#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION) 104#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|\
105 MS_LAZYTIME)
104 106
105/* 107/*
106 * Old magic mount flag and mask 108 * Old magic mount flag and mask
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 7690ec77c722..6dc4580df2af 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -49,10 +49,10 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
49 unsigned long background_thresh; 49 unsigned long background_thresh;
50 unsigned long dirty_thresh; 50 unsigned long dirty_thresh;
51 unsigned long bdi_thresh; 51 unsigned long bdi_thresh;
52 unsigned long nr_dirty, nr_io, nr_more_io; 52 unsigned long nr_dirty, nr_io, nr_more_io, nr_dirty_time;
53 struct inode *inode; 53 struct inode *inode;
54 54
55 nr_dirty = nr_io = nr_more_io = 0; 55 nr_dirty = nr_io = nr_more_io = nr_dirty_time = 0;
56 spin_lock(&wb->list_lock); 56 spin_lock(&wb->list_lock);
57 list_for_each_entry(inode, &wb->b_dirty, i_wb_list) 57 list_for_each_entry(inode, &wb->b_dirty, i_wb_list)
58 nr_dirty++; 58 nr_dirty++;
@@ -60,6 +60,9 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
60 nr_io++; 60 nr_io++;
61 list_for_each_entry(inode, &wb->b_more_io, i_wb_list) 61 list_for_each_entry(inode, &wb->b_more_io, i_wb_list)
62 nr_more_io++; 62 nr_more_io++;
63 list_for_each_entry(inode, &wb->b_dirty_time, i_wb_list)
64 if (inode->i_state & I_DIRTY_TIME)
65 nr_dirty_time++;
63 spin_unlock(&wb->list_lock); 66 spin_unlock(&wb->list_lock);
64 67
65 global_dirty_limits(&background_thresh, &dirty_thresh); 68 global_dirty_limits(&background_thresh, &dirty_thresh);
@@ -78,6 +81,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
78 "b_dirty: %10lu\n" 81 "b_dirty: %10lu\n"
79 "b_io: %10lu\n" 82 "b_io: %10lu\n"
80 "b_more_io: %10lu\n" 83 "b_more_io: %10lu\n"
84 "b_dirty_time: %10lu\n"
81 "bdi_list: %10u\n" 85 "bdi_list: %10u\n"
82 "state: %10lx\n", 86 "state: %10lx\n",
83 (unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)), 87 (unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)),
@@ -91,6 +95,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
91 nr_dirty, 95 nr_dirty,
92 nr_io, 96 nr_io,
93 nr_more_io, 97 nr_more_io,
98 nr_dirty_time,
94 !list_empty(&bdi->bdi_list), bdi->state); 99 !list_empty(&bdi->bdi_list), bdi->state);
95#undef K 100#undef K
96 101
@@ -380,6 +385,7 @@ static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi)
380 INIT_LIST_HEAD(&wb->b_dirty); 385 INIT_LIST_HEAD(&wb->b_dirty);
381 INIT_LIST_HEAD(&wb->b_io); 386 INIT_LIST_HEAD(&wb->b_io);
382 INIT_LIST_HEAD(&wb->b_more_io); 387 INIT_LIST_HEAD(&wb->b_more_io);
388 INIT_LIST_HEAD(&wb->b_dirty_time);
383 spin_lock_init(&wb->list_lock); 389 spin_lock_init(&wb->list_lock);
384 INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn); 390 INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn);
385} 391}