aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2010-10-29 11:16:17 -0400
committerChris Mason <chris.mason@oracle.com>2010-10-29 11:25:29 -0400
commit3259f8bed2f0f57c2fdcdac1b510c3fa319ef97e (patch)
tree5f06f6c83413ca2fc7aec85ba0811a8c91904097
parentcb44921a09221f0a90217b44044448f63190f3e5 (diff)
Add new functions for triggering inode writeback
When btrfs is running low on metadata space, it needs to force delayed allocation pages to disk. It currently does this with a suboptimal walk of a private list of inodes with delayed allocation, and it would be much better if we used the generic flusher threads. writeback_inodes_sb_if_idle would be ideal, but it waits for the flusher thread to start IO on all the dirty pages in the FS before it returns. This adds variants of writeback_inodes_sb* that allow the caller to control how many pages get sent down. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/fs-writeback.c52
-rw-r--r--include/linux/writeback.h2
2 files changed, 44 insertions, 10 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index ab38fef1c9a1..1e23c33ea5cf 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1069,33 +1069,44 @@ static void wait_sb_inodes(struct super_block *sb)
1069} 1069}
1070 1070
1071/** 1071/**
1072 * writeback_inodes_sb - writeback dirty inodes from given super_block 1072 * writeback_inodes_sb_nr - writeback dirty inodes from given super_block
1073 * @sb: the superblock 1073 * @sb: the superblock
1074 * @nr: the number of pages to write
1074 * 1075 *
1075 * Start writeback on some inodes on this super_block. No guarantees are made 1076 * Start writeback on some inodes on this super_block. No guarantees are made
1076 * on how many (if any) will be written, and this function does not wait 1077 * on how many (if any) will be written, and this function does not wait
1077 * for IO completion of submitted IO. The number of pages submitted is 1078 * for IO completion of submitted IO.
1078 * returned.
1079 */ 1079 */
1080void writeback_inodes_sb(struct super_block *sb) 1080void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr)
1081{ 1081{
1082 unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
1083 unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
1084 DECLARE_COMPLETION_ONSTACK(done); 1082 DECLARE_COMPLETION_ONSTACK(done);
1085 struct wb_writeback_work work = { 1083 struct wb_writeback_work work = {
1086 .sb = sb, 1084 .sb = sb,
1087 .sync_mode = WB_SYNC_NONE, 1085 .sync_mode = WB_SYNC_NONE,
1088 .done = &done, 1086 .done = &done,
1087 .nr_pages = nr,
1089 }; 1088 };
1090 1089
1091 WARN_ON(!rwsem_is_locked(&sb->s_umount)); 1090 WARN_ON(!rwsem_is_locked(&sb->s_umount));
1092
1093 work.nr_pages = nr_dirty + nr_unstable +
1094 (inodes_stat.nr_inodes - inodes_stat.nr_unused);
1095
1096 bdi_queue_work(sb->s_bdi, &work); 1091 bdi_queue_work(sb->s_bdi, &work);
1097 wait_for_completion(&done); 1092 wait_for_completion(&done);
1098} 1093}
1094EXPORT_SYMBOL(writeback_inodes_sb_nr);
1095
1096/**
1097 * writeback_inodes_sb - writeback dirty inodes from given super_block
1098 * @sb: the superblock
1099 *
1100 * Start writeback on some inodes on this super_block. No guarantees are made
1101 * on how many (if any) will be written, and this function does not wait
1102 * for IO completion of submitted IO.
1103 */
1104void writeback_inodes_sb(struct super_block *sb)
1105{
1106 return writeback_inodes_sb_nr(sb, global_page_state(NR_FILE_DIRTY) +
1107 global_page_state(NR_UNSTABLE_NFS) +
1108 (inodes_stat.nr_inodes - inodes_stat.nr_unused));
1109}
1099EXPORT_SYMBOL(writeback_inodes_sb); 1110EXPORT_SYMBOL(writeback_inodes_sb);
1100 1111
1101/** 1112/**
@@ -1118,6 +1129,27 @@ int writeback_inodes_sb_if_idle(struct super_block *sb)
1118EXPORT_SYMBOL(writeback_inodes_sb_if_idle); 1129EXPORT_SYMBOL(writeback_inodes_sb_if_idle);
1119 1130
1120/** 1131/**
1132 * writeback_inodes_sb_if_idle - start writeback if none underway
1133 * @sb: the superblock
1134 * @nr: the number of pages to write
1135 *
1136 * Invoke writeback_inodes_sb if no writeback is currently underway.
1137 * Returns 1 if writeback was started, 0 if not.
1138 */
1139int writeback_inodes_sb_nr_if_idle(struct super_block *sb,
1140 unsigned long nr)
1141{
1142 if (!writeback_in_progress(sb->s_bdi)) {
1143 down_read(&sb->s_umount);
1144 writeback_inodes_sb_nr(sb, nr);
1145 up_read(&sb->s_umount);
1146 return 1;
1147 } else
1148 return 0;
1149}
1150EXPORT_SYMBOL(writeback_inodes_sb_nr_if_idle);
1151
1152/**
1121 * sync_inodes_sb - sync sb inode pages 1153 * sync_inodes_sb - sync sb inode pages
1122 * @sb: the superblock 1154 * @sb: the superblock
1123 * 1155 *
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 72a5d647a5f2..a4cf84511e79 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -60,7 +60,9 @@ struct writeback_control {
60struct bdi_writeback; 60struct bdi_writeback;
61int inode_wait(void *); 61int inode_wait(void *);
62void writeback_inodes_sb(struct super_block *); 62void writeback_inodes_sb(struct super_block *);
63void writeback_inodes_sb_nr(struct super_block *, unsigned long nr);
63int writeback_inodes_sb_if_idle(struct super_block *); 64int writeback_inodes_sb_if_idle(struct super_block *);
65int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr);
64void sync_inodes_sb(struct super_block *); 66void sync_inodes_sb(struct super_block *);
65void writeback_inodes_wb(struct bdi_writeback *wb, 67void writeback_inodes_wb(struct bdi_writeback *wb,
66 struct writeback_control *wbc); 68 struct writeback_control *wbc);