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
10691069 }
10701070
10711071 /**
1072− * writeback_inodes_sb - writeback dirty inodes from given super_block
1072+ * writeback_inodes_sb_nr - writeback dirty inodes from given super_block
10731073 * @sb: the superblock
1074+ * @nr: the number of pages to write
10741075 *
10751076 * Start writeback on some inodes on this super_block. No guarantees are made
10761077 * 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− * returned.
1078+ * for IO completion of submitted IO.
10791079 */
1080−void writeback_inodes_sb(struct super_block *sb)
1080+void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr)
10811081 {
1082− unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
1083− unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
10841082 DECLARE_COMPLETION_ONSTACK(done);
10851083 struct wb_writeback_work work = {
10861084 .sb = sb,
10871085 .sync_mode = WB_SYNC_NONE,
10881086 .done = &done,
1087+ .nr_pages = nr,
10891088 };
10901089
10911090 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−
10961091 bdi_queue_work(sb->s_bdi, &work);
10971092 wait_for_completion(&done);
10981093 }
1094+EXPORT_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+ */
1104+void 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+}
10991110 EXPORT_SYMBOL(writeback_inodes_sb);
11001111
11011112 /**
@@ -1117,6 +1128,27 @@ int writeback_inodes_sb_if_idle(struct super_block *sb) · 15 unmodified lines
11171128 }
11181129 EXPORT_SYMBOL(writeback_inodes_sb_if_idle);
11191130
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+ */
1139+int 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+}
1150+EXPORT_SYMBOL(writeback_inodes_sb_nr_if_idle);
1151+
11201152 /**
11211153 * sync_inodes_sb - sync sb inode pages
11221154 * @sb: the superblock
include/linux/writeback.h+2−0
@@ -60,7 +60,9 @@ struct writeback_control { · 59 unmodified lines
6060 struct bdi_writeback;
6161 int inode_wait(void *);
6262 void writeback_inodes_sb(struct super_block *);
63+void writeback_inodes_sb_nr(struct super_block *, unsigned long nr);
6364 int writeback_inodes_sb_if_idle(struct super_block *);
65+int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr);
6466 void sync_inodes_sb(struct super_block *);
6567 void writeback_inodes_wb(struct bdi_writeback *wb,
6668 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