batman-adv: Simplify gw_check_election(), use gw_get_selected()
[firefly-linux-kernel-4.4.55.git] / fs / fs-writeback.c
index efd1ebe879cc6098cfe13a805d69dbf6f0790813..b5ed541fb13773e0df9f2b09f87e71faaf4f82d9 100644 (file)
@@ -175,6 +175,17 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi)
        spin_unlock_bh(&bdi->wb_lock);
 }
 
+/*
+ * Remove the inode from the writeback list it is on.
+ */
+void inode_wb_list_del(struct inode *inode)
+{
+       spin_lock(&inode_wb_list_lock);
+       list_del_init(&inode->i_wb_list);
+       spin_unlock(&inode_wb_list_lock);
+}
+
+
 /*
  * Redirty an inode: set its when-it-was dirtied timestamp and move it to the
  * furthest end of its superblock's dirty-inode list.
@@ -188,6 +199,7 @@ static void redirty_tail(struct inode *inode)
 {
        struct bdi_writeback *wb = &inode_to_bdi(inode)->wb;
 
+       assert_spin_locked(&inode_wb_list_lock);
        if (!list_empty(&wb->b_dirty)) {
                struct inode *tail;
 
@@ -205,14 +217,17 @@ static void requeue_io(struct inode *inode)
 {
        struct bdi_writeback *wb = &inode_to_bdi(inode)->wb;
 
+       assert_spin_locked(&inode_wb_list_lock);
        list_move(&inode->i_wb_list, &wb->b_more_io);
 }
 
 static void inode_sync_complete(struct inode *inode)
 {
        /*
-        * Prevent speculative execution through spin_unlock(&inode_lock);
+        * Prevent speculative execution through
+        * spin_unlock(&inode_wb_list_lock);
         */
+
        smp_mb();
        wake_up_bit(&inode->i_state, __I_SYNC);
 }
@@ -286,6 +301,7 @@ static void move_expired_inodes(struct list_head *delaying_queue,
  */
 static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this)
 {
+       assert_spin_locked(&inode_wb_list_lock);
        list_splice_init(&wb->b_more_io, &wb->b_io);
        move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
 }
@@ -308,25 +324,23 @@ static void inode_wait_for_writeback(struct inode *inode)
        wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
        while (inode->i_state & I_SYNC) {
                spin_unlock(&inode->i_lock);
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_wb_list_lock);
                __wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE);
-               spin_lock(&inode_lock);
+               spin_lock(&inode_wb_list_lock);
                spin_lock(&inode->i_lock);
        }
 }
 
 /*
- * Write out an inode's dirty pages.  Called under inode_lock.  Either the
- * caller has ref on the inode (either via __iget or via syscall against an fd)
- * or the inode has I_WILL_FREE set (via generic_forget_inode)
+ * Write out an inode's dirty pages.  Called under inode_wb_list_lock and
+ * inode->i_lock.  Either the caller has an active reference on the inode or
+ * the inode has I_WILL_FREE set.
  *
  * If `wait' is set, wait on the writeout.
  *
  * The whole writeout design is quite complex and fragile.  We want to avoid
  * starvation of particular inodes when others are being redirtied, prevent
  * livelocks, etc.
- *
- * Called under inode_lock.
  */
 static int
 writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
@@ -335,7 +349,9 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
        unsigned dirty;
        int ret;
 
-       spin_lock(&inode->i_lock);
+       assert_spin_locked(&inode_wb_list_lock);
+       assert_spin_locked(&inode->i_lock);
+
        if (!atomic_read(&inode->i_count))
                WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
        else
@@ -351,7 +367,6 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
                 * completed a full scan of b_io.
                 */
                if (wbc->sync_mode != WB_SYNC_ALL) {
-                       spin_unlock(&inode->i_lock);
                        requeue_io(inode);
                        return 0;
                }
@@ -368,7 +383,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
        inode->i_state |= I_SYNC;
        inode->i_state &= ~I_DIRTY_PAGES;
        spin_unlock(&inode->i_lock);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_wb_list_lock);
 
        ret = do_writepages(mapping, wbc);
 
@@ -388,12 +403,10 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
         * due to delalloc, clear dirty metadata flags right before
         * write_inode()
         */
-       spin_lock(&inode_lock);
        spin_lock(&inode->i_lock);
        dirty = inode->i_state & I_DIRTY;
        inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
        spin_unlock(&inode->i_lock);
-       spin_unlock(&inode_lock);
        /* Don't write the inode if only I_DIRTY_PAGES was set */
        if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
                int err = write_inode(inode, wbc);
@@ -401,7 +414,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
                        ret = err;
        }
 
-       spin_lock(&inode_lock);
+       spin_lock(&inode_wb_list_lock);
        spin_lock(&inode->i_lock);
        inode->i_state &= ~I_SYNC;
        if (!(inode->i_state & I_FREEING)) {
@@ -444,7 +457,6 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
                }
        }
        inode_sync_complete(inode);
-       spin_unlock(&inode->i_lock);
        return ret;
 }
 
@@ -532,7 +544,6 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb,
                }
 
                __iget(inode);
-               spin_unlock(&inode->i_lock);
 
                pages_skipped = wbc->pages_skipped;
                writeback_single_inode(inode, wbc);
@@ -543,10 +554,11 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb,
                         */
                        redirty_tail(inode);
                }
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode->i_lock);
+               spin_unlock(&inode_wb_list_lock);
                iput(inode);
                cond_resched();
-               spin_lock(&inode_lock);
+               spin_lock(&inode_wb_list_lock);
                if (wbc->nr_to_write <= 0) {
                        wbc->more_io = 1;
                        return 1;
@@ -565,7 +577,7 @@ void writeback_inodes_wb(struct bdi_writeback *wb,
 
        if (!wbc->wb_start)
                wbc->wb_start = jiffies; /* livelock avoidance */
-       spin_lock(&inode_lock);
+       spin_lock(&inode_wb_list_lock);
        if (!wbc->for_kupdate || list_empty(&wb->b_io))
                queue_io(wb, wbc->older_than_this);
 
@@ -583,7 +595,7 @@ void writeback_inodes_wb(struct bdi_writeback *wb,
                if (ret)
                        break;
        }
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_wb_list_lock);
        /* Leave any unwritten inodes on b_io */
 }
 
@@ -592,11 +604,11 @@ static void __writeback_inodes_sb(struct super_block *sb,
 {
        WARN_ON(!rwsem_is_locked(&sb->s_umount));
 
-       spin_lock(&inode_lock);
+       spin_lock(&inode_wb_list_lock);
        if (!wbc->for_kupdate || list_empty(&wb->b_io))
                queue_io(wb, wbc->older_than_this);
        writeback_sb_inodes(sb, wb, wbc, true);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_wb_list_lock);
 }
 
 /*
@@ -735,7 +747,7 @@ static long wb_writeback(struct bdi_writeback *wb,
                 * become available for writeback. Otherwise
                 * we'll just busyloop.
                 */
-               spin_lock(&inode_lock);
+               spin_lock(&inode_wb_list_lock);
                if (!list_empty(&wb->b_more_io))  {
                        inode = wb_inode(wb->b_more_io.prev);
                        trace_wbc_writeback_wait(&wbc, wb->bdi);
@@ -743,7 +755,7 @@ static long wb_writeback(struct bdi_writeback *wb,
                        inode_wait_for_writeback(inode);
                        spin_unlock(&inode->i_lock);
                }
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_wb_list_lock);
        }
 
        return wrote;
@@ -1009,7 +1021,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 {
        struct super_block *sb = inode->i_sb;
        struct backing_dev_info *bdi = NULL;
-       bool wakeup_bdi = false;
 
        /*
         * Don't do this for I_DIRTY_PAGES - that doesn't actually
@@ -1033,7 +1044,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
        if (unlikely(block_dump))
                block_dump___mark_inode_dirty(inode);
 
-       spin_lock(&inode_lock);
        spin_lock(&inode->i_lock);
        if ((inode->i_state & flags) != flags) {
                const int was_dirty = inode->i_state & I_DIRTY;
@@ -1059,12 +1069,12 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                if (inode->i_state & I_FREEING)
                        goto out_unlock_inode;
 
-               spin_unlock(&inode->i_lock);
                /*
                 * If the inode was already on b_dirty/b_io/b_more_io, don't
                 * reposition it (that would break b_dirty time-ordering).
                 */
                if (!was_dirty) {
+                       bool wakeup_bdi = false;
                        bdi = inode_to_bdi(inode);
 
                        if (bdi_cap_writeback_dirty(bdi)) {
@@ -1081,18 +1091,20 @@ void __mark_inode_dirty(struct inode *inode, int flags)
                                        wakeup_bdi = true;
                        }
 
+                       spin_unlock(&inode->i_lock);
+                       spin_lock(&inode_wb_list_lock);
                        inode->dirtied_when = jiffies;
                        list_move(&inode->i_wb_list, &bdi->wb.b_dirty);
+                       spin_unlock(&inode_wb_list_lock);
+
+                       if (wakeup_bdi)
+                               bdi_wakeup_thread_delayed(bdi);
+                       return;
                }
-               goto out;
        }
 out_unlock_inode:
        spin_unlock(&inode->i_lock);
-out:
-       spin_unlock(&inode_lock);
 
-       if (wakeup_bdi)
-               bdi_wakeup_thread_delayed(bdi);
 }
 EXPORT_SYMBOL(__mark_inode_dirty);
 
@@ -1123,7 +1135,7 @@ static void wait_sb_inodes(struct super_block *sb)
         */
        WARN_ON(!rwsem_is_locked(&sb->s_umount));
 
-       spin_lock(&inode_lock);
+       spin_lock(&inode_sb_list_lock);
 
        /*
         * Data integrity sync. Must wait for all pages under writeback,
@@ -1143,14 +1155,15 @@ static void wait_sb_inodes(struct super_block *sb)
                }
                __iget(inode);
                spin_unlock(&inode->i_lock);
-               spin_unlock(&inode_lock);
+               spin_unlock(&inode_sb_list_lock);
+
                /*
-                * We hold a reference to 'inode' so it couldn't have
-                * been removed from s_inodes list while we dropped the
-                * inode_lock.  We cannot iput the inode now as we can
-                * be holding the last reference and we cannot iput it
-                * under inode_lock. So we keep the reference and iput
-                * it later.
+                * We hold a reference to 'inode' so it couldn't have been
+                * removed from s_inodes list while we dropped the
+                * inode_sb_list_lock.  We cannot iput the inode now as we can
+                * be holding the last reference and we cannot iput it under
+                * inode_sb_list_lock. So we keep the reference and iput it
+                * later.
                 */
                iput(old_inode);
                old_inode = inode;
@@ -1159,9 +1172,9 @@ static void wait_sb_inodes(struct super_block *sb)
 
                cond_resched();
 
-               spin_lock(&inode_lock);
+               spin_lock(&inode_sb_list_lock);
        }
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode_sb_list_lock);
        iput(old_inode);
 }
 
@@ -1295,9 +1308,11 @@ int write_inode_now(struct inode *inode, int sync)
                wbc.nr_to_write = 0;
 
        might_sleep();
-       spin_lock(&inode_lock);
+       spin_lock(&inode_wb_list_lock);
+       spin_lock(&inode->i_lock);
        ret = writeback_single_inode(inode, &wbc);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode->i_lock);
+       spin_unlock(&inode_wb_list_lock);
        if (sync)
                inode_sync_wait(inode);
        return ret;
@@ -1319,9 +1334,11 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
 {
        int ret;
 
-       spin_lock(&inode_lock);
+       spin_lock(&inode_wb_list_lock);
+       spin_lock(&inode->i_lock);
        ret = writeback_single_inode(inode, wbc);
-       spin_unlock(&inode_lock);
+       spin_unlock(&inode->i_lock);
+       spin_unlock(&inode_wb_list_lock);
        return ret;
 }
 EXPORT_SYMBOL(sync_inode);