Merge branch 'SLE11-SP1' of ssh://kerncvs.suse.de/home/git/kernel-source into SLE11-SP1
Conflicts:
series.conf
suse-commit: 7da281afbd78855773911f3b44d7d45efa04ec20
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 36e16a2..4584cb0 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -42,7 +42,6 @@
int for_kupdate:1;
int range_cyclic:1;
int for_background:1;
- int locked:1;
};
/*
@@ -159,23 +158,6 @@
}
}
-/* Wakeup flusher thread or forker thread to fork it. */
-static void bdi_wakeup_flusher(struct backing_dev_info *bdi)
-{
- /*
- * If the default thread isn't there, make sure we add it. When
- * it gets created and wakes up, we'll run this work.
- */
- if (unlikely(list_empty_careful(&bdi->wb_list)))
- wake_up_process(default_backing_dev_info.wb.task);
- else {
- struct bdi_writeback *wb = &bdi->wb;
-
- if (wb->task)
- wake_up_process(wb->task);
- }
-}
-
static void bdi_queue_work(struct backing_dev_info *bdi, struct bdi_work *work)
{
work->seen = bdi->wb_mask;
@@ -191,7 +173,19 @@
spin_lock(&bdi->wb_lock);
list_add_tail_rcu(&work->list, &bdi->work_list);
spin_unlock(&bdi->wb_lock);
- bdi_wakeup_flusher(bdi);
+
+ /*
+ * If the default thread isn't there, make sure we add it. When
+ * it gets created and wakes up, we'll run this work.
+ */
+ if (unlikely(list_empty_careful(&bdi->wb_list)))
+ wake_up_process(default_backing_dev_info.wb.task);
+ else {
+ struct bdi_writeback *wb = &bdi->wb;
+
+ if (wb->task)
+ wake_up_process(wb->task);
+ }
}
/*
@@ -243,7 +237,6 @@
.sync_mode = WB_SYNC_ALL,
.nr_pages = LONG_MAX,
.range_cyclic = 0,
- .locked = 1,
};
struct bdi_work work;
@@ -266,14 +259,13 @@
*
*/
void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
- long nr_pages, int locked)
+ long nr_pages)
{
struct wb_writeback_args args = {
.sb = sb,
.sync_mode = WB_SYNC_NONE,
.nr_pages = nr_pages,
.range_cyclic = 1,
- .locked = locked,
};
/*
@@ -281,26 +273,11 @@
* ie. to sync pages until the background dirty threshold is reached.
*/
if (!nr_pages) {
- /*
- * We just wake up the flusher thread. It will perform
- * background writeback as soon as there is no other work to
- * do.
- */
- bdi_wakeup_flusher(bdi);
- return;
+ args.nr_pages = LONG_MAX;
+ args.for_background = 1;
}
- if (locked) {
- struct bdi_work work;
-
- bdi_work_init(&work, &args);
- work.state |= WS_ONSTACK;
-
- bdi_queue_work(bdi, &work);
- bdi_wait_on_work_clear(&work);
- } else {
- bdi_alloc_queue_work(bdi, &args);
- }
+ bdi_alloc_queue_work(bdi, &args);
}
/*
@@ -598,9 +575,11 @@
* Returns 0 if the super was successfully pinned (or pinning wasn't needed),
* 1 if we failed.
*/
-static int pin_sb_for_writeback(struct super_block *sb, int locked,
- struct super_block **psb)
+static int pin_sb_for_writeback(struct writeback_control *wbc,
+ struct inode *inode, struct super_block **psb)
{
+ struct super_block *sb = inode->i_sb;
+
/*
* If this sb is already pinned, nothing more to do. If not and
* *psb is non-NULL, unpin the old one first
@@ -613,7 +592,7 @@
/*
* Caller must already hold the ref for this
*/
- if (locked) {
+ if (wbc->sync_mode == WB_SYNC_ALL) {
WARN_ON(!rwsem_is_locked(&sb->s_umount));
return 0;
}
@@ -640,11 +619,11 @@
}
static void writeback_inodes_wb(struct bdi_writeback *wb,
- struct writeback_control *wbc, int locked,
- unsigned long start_jif)
+ struct writeback_control *wbc)
{
struct super_block *sb = wbc->sb, *pin_sb = NULL;
const int is_blkdev_sb = sb_is_blkdev_sb(sb);
+ const unsigned long start = jiffies; /* livelock avoidance */
spin_lock(&inode_lock);
@@ -698,10 +677,10 @@
* Was this inode dirtied after sync_sb_inodes was called?
* This keeps sync from extra jobs and livelock.
*/
- if (inode_dirtied_after(inode, start_jif))
+ if (inode_dirtied_after(inode, start))
break;
- if (pin_sb_for_writeback(sb, locked, &pin_sb)) {
+ if (pin_sb_for_writeback(wbc, inode, &pin_sb)) {
requeue_io(inode);
continue;
}
@@ -739,8 +718,7 @@
{
struct backing_dev_info *bdi = wbc->bdi;
- writeback_inodes_wb(&bdi->wb, wbc, wbc->sync_mode == WB_SYNC_ALL,
- jiffies);
+ writeback_inodes_wb(&bdi->wb, wbc);
}
/*
@@ -762,24 +740,6 @@
global_page_state(NR_UNSTABLE_NFS) >= background_thresh);
}
-/* Is there unprocessed work in the list? */
-static int wb_work_pending(struct backing_dev_info *bdi,
- struct bdi_writeback *wb)
-{
- struct bdi_work *work;
- int ret = 0;
-
- rcu_read_lock();
- list_for_each_entry_rcu(work, &bdi->work_list, list) {
- if (test_bit(wb->nr, &work->seen)) {
- ret = 1;
- break;
- }
- }
- rcu_read_unlock();
- return ret;
-}
-
/*
* Explicit flushing or periodic writeback of "old" data.
*
@@ -808,9 +768,7 @@
};
unsigned long oldest_jif;
long wrote = 0;
- long write_chunk;
struct inode *inode;
- unsigned long start_jif = jiffies; /* Livelock avoidance */
if (wbc.for_kupdate) {
wbc.older_than_this = &oldest_jif;
@@ -822,17 +780,6 @@
wbc.range_end = LLONG_MAX;
}
- /*
- * For WB_SYNC_ALL mode, write_cache_pages() writes the whole inode
- * regardless of wbc.nr_to_write and subsequent logic in wb_writeback()
- * will requeue inode for another round if wbc.nr_to_write <= 0 which
- * isn't needed in WB_SYNC_ALL mode.
- */
- if (wbc.sync_mode == WB_SYNC_NONE)
- write_chunk = MAX_WRITEBACK_PAGES;
- else
- write_chunk = LONG_MAX;
-
for (;;) {
/*
* Stop writeback when nr_pages has been consumed
@@ -841,16 +788,6 @@
break;
/*
- * Background writeout and kupdate-style writeback may
- * run forever. Stop them if there is other work to do
- * so that e.g. sync can proceed. They'll be restarted
- * after the other works are all done.
- */
- if ((args->for_background || args->for_kupdate) &&
- wb_work_pending(wb->bdi, wb))
- break;
-
- /*
* For background writeout, stop when we are below the
* background dirty threshold
*/
@@ -859,11 +796,11 @@
wbc.more_io = 0;
wbc.encountered_congestion = 0;
- wbc.nr_to_write = write_chunk;
+ wbc.nr_to_write = MAX_WRITEBACK_PAGES;
wbc.pages_skipped = 0;
- writeback_inodes_wb(wb, &wbc, args->locked, start_jif);
- args->nr_pages -= write_chunk - wbc.nr_to_write;
- wrote += write_chunk - wbc.nr_to_write;
+ writeback_inodes_wb(wb, &wbc);
+ args->nr_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
+ wrote += MAX_WRITEBACK_PAGES - wbc.nr_to_write;
/*
* If we consumed everything, see if we have more
@@ -878,7 +815,7 @@
/*
* Did we write something? Try for more
*/
- if (wbc.nr_to_write < write_chunk)
+ if (wbc.nr_to_write < MAX_WRITEBACK_PAGES)
continue;
/*
* Nothing written. Wait for some inode to
@@ -960,22 +897,6 @@
return 0;
}
-static long wb_check_background_flush(struct bdi_writeback *wb)
-{
- if (over_bground_thresh()) {
- struct wb_writeback_args args = {
- .nr_pages = LONG_MAX,
- .sync_mode = WB_SYNC_NONE,
- .for_background = 1,
- .range_cyclic = 1,
- };
-
- return wb_writeback(wb, &args);
- }
-
- return 0;
-}
-
/*
* Retrieve work items and do the writeback they describe
*/
@@ -998,7 +919,7 @@
* If this isn't a data integrity operation, just notify
* that we have seen this work and we are now starting it.
*/
- if (args.sync_mode == WB_SYNC_NONE && !args.locked)
+ if (args.sync_mode == WB_SYNC_NONE)
wb_clear_pending(wb, work);
wrote += wb_writeback(wb, &args);
@@ -1007,15 +928,14 @@
* This is a data integrity writeback, so only do the
* notification when we have completed the work.
*/
- if (args.sync_mode == WB_SYNC_ALL || args.locked)
+ if (args.sync_mode == WB_SYNC_ALL)
wb_clear_pending(wb, work);
}
/*
- * Check for periodic writeback, kupdated()+pdflush() style
+ * Check for periodic writeback, kupdated() style
*/
wrote += wb_check_old_data_flush(wb);
- wrote += wb_check_background_flush(wb);
return wrote;
}
@@ -1291,7 +1211,6 @@
/**
* writeback_inodes_sb - writeback dirty inodes from given super_block
* @sb: the superblock
- * @locked: sb already pinned
*
* Start writeback on some inodes on this super_block. No guarantees are made
* on how many (if any) will be written, and this function does not wait
@@ -1300,12 +1219,6 @@
*/
void writeback_inodes_sb(struct super_block *sb)
{
- writeback_inodes_sb_locked(sb, 0);
-}
-EXPORT_SYMBOL(writeback_inodes_sb);
-
-void writeback_inodes_sb_locked(struct super_block *sb, int locked)
-{
unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
long nr_to_write;
@@ -1313,9 +1226,9 @@
nr_to_write = nr_dirty + nr_unstable +
(inodes_stat.nr_inodes - inodes_stat.nr_unused);
- bdi_start_writeback(sb->s_bdi, sb, nr_to_write, locked);
+ bdi_start_writeback(sb->s_bdi, sb, nr_to_write);
}
-EXPORT_SYMBOL(writeback_inodes_sb_locked);
+EXPORT_SYMBOL(writeback_inodes_sb);
/**
* writeback_inodes_sb_if_idle - start writeback if none underway
@@ -1327,7 +1240,7 @@
int writeback_inodes_sb_if_idle(struct super_block *sb)
{
if (!writeback_in_progress(sb->s_bdi)) {
- writeback_inodes_sb_locked(sb, 0);
+ writeback_inodes_sb(sb);
return 1;
} else
return 0;
diff --git a/fs/sync.c b/fs/sync.c
index 72fcd91..d104591 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -37,7 +37,7 @@
/* Avoid doing twice syncing and cache pruning for quota sync */
if (!wait) {
writeout_quota_sb(sb, -1);
- writeback_inodes_sb_locked(sb, 1);
+ writeback_inodes_sb(sb);
} else {
sync_quota_sb(sb, -1);
sync_inodes_sb(sb);
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 965ccd8e..076ca50 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -62,7 +62,7 @@
*/
static void shrink_liability(struct ubifs_info *c, int nr_to_write)
{
- writeback_inodes_sb_locked(c->vfs_sb, 0);
+ writeback_inodes_sb(c->vfs_sb);
}
/**
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index ce997ba5..b449e73 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -102,7 +102,7 @@
int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
void bdi_unregister(struct backing_dev_info *bdi);
void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
- long nr_pages, int locked);
+ long nr_pages);
int bdi_writeback_task(struct bdi_writeback *wb);
int bdi_has_dirty_io(struct backing_dev_info *bdi);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 132ad8e..8f36a7e 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -69,7 +69,6 @@
struct bdi_writeback;
int inode_wait(void *);
void writeback_inodes_sb(struct super_block *);
-void writeback_inodes_sb_locked(struct super_block *, int);
int writeback_inodes_sb_if_idle(struct super_block *);
void sync_inodes_sb(struct super_block *);
void writeback_inodes_wbc(struct writeback_control *wbc);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 1569b77..66e4c29 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -597,7 +597,7 @@
(!laptop_mode && ((global_page_state(NR_FILE_DIRTY)
+ global_page_state(NR_UNSTABLE_NFS))
> background_thresh)))
- bdi_start_writeback(bdi, NULL, 0, 0);
+ bdi_start_writeback(bdi, NULL, 0);
}
void set_page_dirty_balance(struct page *page, int page_mkwrite)