aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-09-02 03:19:46 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-09-11 03:20:25 -0400
commit66f3b8e2e103a0b93b945764d98e9ba46cb926dd (patch)
tree442bf5664214f0a1448e4010b09868cc58fdd3d1 /mm
parentd8a8559cd7a9ccac98d5f6f13297a2ff68a43627 (diff)
writeback: move dirty inodes from super_block to backing_dev_info
This is a first step at introducing per-bdi flusher threads. We should have no change in behaviour, although sb_has_dirty_inodes() is now ridiculously expensive, as there's no easy way to answer that question. Not a huge problem, since it'll be deleted in subsequent patches. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'mm')
-rw-r--r--mm/backing-dev.c24
-rw-r--r--mm/page-writeback.c11
2 files changed, 28 insertions, 7 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index c86edd244294..6f163e0f0509 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -22,6 +22,8 @@ struct backing_dev_info default_backing_dev_info = {
22EXPORT_SYMBOL_GPL(default_backing_dev_info); 22EXPORT_SYMBOL_GPL(default_backing_dev_info);
23 23
24static struct class *bdi_class; 24static struct class *bdi_class;
25DEFINE_MUTEX(bdi_lock);
26LIST_HEAD(bdi_list);
25 27
26#ifdef CONFIG_DEBUG_FS 28#ifdef CONFIG_DEBUG_FS
27#include <linux/debugfs.h> 29#include <linux/debugfs.h>
@@ -211,6 +213,10 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
211 goto exit; 213 goto exit;
212 } 214 }
213 215
216 mutex_lock(&bdi_lock);
217 list_add_tail(&bdi->bdi_list, &bdi_list);
218 mutex_unlock(&bdi_lock);
219
214 bdi->dev = dev; 220 bdi->dev = dev;
215 bdi_debug_register(bdi, dev_name(dev)); 221 bdi_debug_register(bdi, dev_name(dev));
216 222
@@ -225,9 +231,17 @@ int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev)
225} 231}
226EXPORT_SYMBOL(bdi_register_dev); 232EXPORT_SYMBOL(bdi_register_dev);
227 233
234static void bdi_remove_from_list(struct backing_dev_info *bdi)
235{
236 mutex_lock(&bdi_lock);
237 list_del(&bdi->bdi_list);
238 mutex_unlock(&bdi_lock);
239}
240
228void bdi_unregister(struct backing_dev_info *bdi) 241void bdi_unregister(struct backing_dev_info *bdi)
229{ 242{
230 if (bdi->dev) { 243 if (bdi->dev) {
244 bdi_remove_from_list(bdi);
231 bdi_debug_unregister(bdi); 245 bdi_debug_unregister(bdi);
232 device_unregister(bdi->dev); 246 device_unregister(bdi->dev);
233 bdi->dev = NULL; 247 bdi->dev = NULL;
@@ -245,6 +259,10 @@ int bdi_init(struct backing_dev_info *bdi)
245 bdi->min_ratio = 0; 259 bdi->min_ratio = 0;
246 bdi->max_ratio = 100; 260 bdi->max_ratio = 100;
247 bdi->max_prop_frac = PROP_FRAC_BASE; 261 bdi->max_prop_frac = PROP_FRAC_BASE;
262 INIT_LIST_HEAD(&bdi->bdi_list);
263 INIT_LIST_HEAD(&bdi->b_io);
264 INIT_LIST_HEAD(&bdi->b_dirty);
265 INIT_LIST_HEAD(&bdi->b_more_io);
248 266
249 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) { 267 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) {
250 err = percpu_counter_init(&bdi->bdi_stat[i], 0); 268 err = percpu_counter_init(&bdi->bdi_stat[i], 0);
@@ -259,6 +277,8 @@ int bdi_init(struct backing_dev_info *bdi)
259err: 277err:
260 while (i--) 278 while (i--)
261 percpu_counter_destroy(&bdi->bdi_stat[i]); 279 percpu_counter_destroy(&bdi->bdi_stat[i]);
280
281 bdi_remove_from_list(bdi);
262 } 282 }
263 283
264 return err; 284 return err;
@@ -269,6 +289,10 @@ void bdi_destroy(struct backing_dev_info *bdi)
269{ 289{
270 int i; 290 int i;
271 291
292 WARN_ON(!list_empty(&bdi->b_dirty));
293 WARN_ON(!list_empty(&bdi->b_io));
294 WARN_ON(!list_empty(&bdi->b_more_io));
295
272 bdi_unregister(bdi); 296 bdi_unregister(bdi);
273 297
274 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) 298 for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 81627ebcd313..f8341b6019bf 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -320,15 +320,13 @@ static void task_dirty_limit(struct task_struct *tsk, unsigned long *pdirty)
320/* 320/*
321 * 321 *
322 */ 322 */
323static DEFINE_SPINLOCK(bdi_lock);
324static unsigned int bdi_min_ratio; 323static unsigned int bdi_min_ratio;
325 324
326int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio) 325int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
327{ 326{
328 int ret = 0; 327 int ret = 0;
329 unsigned long flags;
330 328
331 spin_lock_irqsave(&bdi_lock, flags); 329 mutex_lock(&bdi_lock);
332 if (min_ratio > bdi->max_ratio) { 330 if (min_ratio > bdi->max_ratio) {
333 ret = -EINVAL; 331 ret = -EINVAL;
334 } else { 332 } else {
@@ -340,27 +338,26 @@ int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
340 ret = -EINVAL; 338 ret = -EINVAL;
341 } 339 }
342 } 340 }
343 spin_unlock_irqrestore(&bdi_lock, flags); 341 mutex_unlock(&bdi_lock);
344 342
345 return ret; 343 return ret;
346} 344}
347 345
348int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned max_ratio) 346int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned max_ratio)
349{ 347{
350 unsigned long flags;
351 int ret = 0; 348 int ret = 0;
352 349
353 if (max_ratio > 100) 350 if (max_ratio > 100)
354 return -EINVAL; 351 return -EINVAL;
355 352
356 spin_lock_irqsave(&bdi_lock, flags); 353 mutex_lock(&bdi_lock);
357 if (bdi->min_ratio > max_ratio) { 354 if (bdi->min_ratio > max_ratio) {
358 ret = -EINVAL; 355 ret = -EINVAL;
359 } else { 356 } else {
360 bdi->max_ratio = max_ratio; 357 bdi->max_ratio = max_ratio;
361 bdi->max_prop_frac = (PROP_FRAC_BASE * max_ratio) / 100; 358 bdi->max_prop_frac = (PROP_FRAC_BASE * max_ratio) / 100;
362 } 359 }
363 spin_unlock_irqrestore(&bdi_lock, flags); 360 mutex_unlock(&bdi_lock);
364 361
365 return ret; 362 return ret;
366} 363}