writeback: check for registered bdi in flusher add and inode dirty
authorJens Axboe <jens.axboe@oracle.com>
Wed, 9 Sep 2009 07:10:25 +0000 (09:10 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 11 Sep 2009 07:20:26 +0000 (09:20 +0200)
Also a debugging aid. We want to catch dirty inodes being added to
backing devices that don't do writeback.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fs/fs-writeback.c
include/linux/backing-dev.h
mm/backing-dev.c

index 2e601ce581c9ccf7a50f1016a6df690892607c56..da86ef58e4278654b9ae721e73c0ce9815b19b40 100644 (file)
@@ -1046,6 +1046,14 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                 */
                if (!was_dirty) {
                        struct bdi_writeback *wb = &inode_to_bdi(inode)->wb;
+                       struct backing_dev_info *bdi = wb->bdi;
+
+                       if (bdi_cap_writeback_dirty(bdi) &&
+                           !test_bit(BDI_registered, &bdi->state)) {
+                               WARN_ON(1);
+                               printk(KERN_ERR "bdi-%s not registered\n",
+                                                               bdi->name);
+                       }
 
                        inode->dirtied_when = jiffies;
                        list_move(&inode->i_list, &wb->b_dirty);
index 2f218b7cb063a72fc7619f1e87a6fc27ca63a8ec..f169bcb90b58b3b098208984a50a921132bd9f5f 100644 (file)
@@ -29,6 +29,7 @@ enum bdi_state {
        BDI_wb_alloc,           /* Default embedded wb allocated */
        BDI_async_congested,    /* The async (write) queue is getting full */
        BDI_sync_congested,     /* The sync queue is getting full */
+       BDI_registered,         /* bdi_register() was done */
        BDI_unused,             /* Available bits start here */
 };
 
index 5cb32c5b93d829b25d120cc2b8aa6ddd919e52bc..d3ca0dac1111ed4f22cba933acf535a85f43b3aa 100644 (file)
@@ -465,6 +465,12 @@ void static bdi_add_default_flusher_task(struct backing_dev_info *bdi)
        if (!bdi_cap_writeback_dirty(bdi))
                return;
 
+       if (WARN_ON(!test_bit(BDI_registered, &bdi->state))) {
+               printk(KERN_ERR "bdi %p/%s is not registered!\n",
+                                                       bdi, bdi->name);
+               return;
+       }
+
        /*
         * Check with the helper whether to proceed adding a task. Will only
         * abort if we two or more simultanous calls to
@@ -528,6 +534,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
        }
 
        bdi_debug_register(bdi, dev_name(dev));
+       set_bit(BDI_registered, &bdi->state);
 exit:
        return ret;
 }