History

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.

Chris Mason committed 16 years ago

Commit 3259f8b1 parent cb449212 files · +44 −10Browse files

Unified · Split

2 files
  1. fs/fs-writeback.c +42 −10
  2. include/linux/writeback.h +2 −0
fs/fs-writeback.c+42−10
@@ -1069,33 +1069,44 @@ static void wait_sb_inodes(struct super_block *sb) · 1068 unmodified lines
1069}1069}
1070 1070
1071/**1071/**
1072 * writeback_inodes_sb - writeback dirty inodes from given super_block1072 * writeback_inodes_sb_nr - writeback dirty inodes from given super_block
1073 * @sb: the superblock1073 * @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 made1076 * 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 wait1077 * 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 is1078 * 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/**
@@ -1117,6 +1128,27 @@ int writeback_inodes_sb_if_idle(struct super_block *sb) · 15 unmodified lines
1117}1128}
1118EXPORT_SYMBOL(writeback_inodes_sb_if_idle);1129EXPORT_SYMBOL(writeback_inodes_sb_if_idle);
1119 1130
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
1120/**1152/**
1121 * sync_inodes_sb - sync sb inode pages1153 * sync_inodes_sb - sync sb inode pages
1122 * @sb: the superblock1154 * @sb: the superblock
include/linux/writeback.h+2−0
@@ -60,7 +60,9 @@ struct writeback_control { · 59 unmodified lines
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);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t