]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Move __set_page_dirty_buffers to fs/buffer.c
authorAndrew Morton <akpm@digeo.com>
Sun, 20 Apr 2003 07:27:14 +0000 (00:27 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 20 Apr 2003 07:27:14 +0000 (00:27 -0700)
From: William Lee Irwin III <wli@holomorphy.com>

Move __set_page_dirty_buffers() to fs/buffer.c, as per the FIXME.

fs/buffer.c
mm/page-writeback.c

index 006892c691cdd04a6359402cccf439d72ae4f169..c40bf36afc0b13a3af84e4213ce14417118d0ba9 100644 (file)
@@ -775,6 +775,85 @@ void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
 }
 EXPORT_SYMBOL(mark_buffer_dirty_inode);
 
+/*
+ * Add a page to the dirty page list.
+ *
+ * It is a sad fact of life that this function is called from several places
+ * deeply under spinlocking.  It may not sleep.
+ *
+ * If the page has buffers, the uptodate buffers are set dirty, to preserve
+ * dirty-state coherency between the page and the buffers.  It the page does
+ * not have buffers then when they are later attached they will all be set
+ * dirty.
+ *
+ * The buffers are dirtied before the page is dirtied.  There's a small race
+ * window in which a writepage caller may see the page cleanness but not the
+ * buffer dirtiness.  That's fine.  If this code were to set the page dirty
+ * before the buffers, a concurrent writepage caller could clear the page dirty
+ * bit, see a bunch of clean buffers and we'd end up with dirty buffers/clean
+ * page on the dirty page list.
+ *
+ * There is also a small window where the page is dirty, and not on dirty_pages.
+ * Also a possibility that by the time the page is added to dirty_pages, it has
+ * been set clean.  The page lists are somewhat approximate in this regard.
+ * It's better to have clean pages accidentally attached to dirty_pages than to
+ * leave dirty pages attached to clean_pages.
+ *
+ * We use private_lock to lock against try_to_free_buffers while using the
+ * page's buffer list.  Also use this to protect against clean buffers being
+ * added to the page after it was set dirty.
+ *
+ * FIXME: may need to call ->reservepage here as well.  That's rather up to the
+ * address_space though.
+ *
+ * For now, we treat swapper_space specially.  It doesn't use the normal
+ * block a_ops.
+ */
+int __set_page_dirty_buffers(struct page *page)
+{
+       struct address_space * const mapping = page->mapping;
+       int ret = 0;
+
+       if (mapping == NULL) {
+               SetPageDirty(page);
+               goto out;
+       }
+
+       if (!PageUptodate(page))
+               buffer_error();
+
+       spin_lock(&mapping->private_lock);
+       if (page_has_buffers(page)) {
+               struct buffer_head *head = page_buffers(page);
+               struct buffer_head *bh = head;
+
+               do {
+                       if (buffer_uptodate(bh))
+                               set_buffer_dirty(bh);
+                       else
+                               buffer_error();
+                       bh = bh->b_this_page;
+               } while (bh != head);
+       }
+       spin_unlock(&mapping->private_lock);
+
+       if (!TestSetPageDirty(page)) {
+               spin_lock(&mapping->page_lock);
+               if (page->mapping) {    /* Race with truncate? */
+                       if (!mapping->backing_dev_info->memory_backed)
+                               inc_page_state(nr_dirty);
+                       list_del(&page->list);
+                       list_add(&page->list, &mapping->dirty_pages);
+               }
+               spin_unlock(&mapping->page_lock);
+               __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+       }
+       
+out:
+       return ret;
+}
+EXPORT_SYMBOL(__set_page_dirty_buffers);
+
 /*
  * Write out and wait upon a list of buffers.
  *
index aaa70d02b85958c1333daf450a19f4460246f789..c33c6a207426bbf2cd320ddabaa2ec26bf009ffc 100644 (file)
@@ -461,88 +461,6 @@ int write_one_page(struct page *page, int wait)
 }
 EXPORT_SYMBOL(write_one_page);
 
-/*
- * Add a page to the dirty page list.
- *
- * It is a sad fact of life that this function is called from several places
- * deeply under spinlocking.  It may not sleep.
- *
- * If the page has buffers, the uptodate buffers are set dirty, to preserve
- * dirty-state coherency between the page and the buffers.  It the page does
- * not have buffers then when they are later attached they will all be set
- * dirty.
- *
- * The buffers are dirtied before the page is dirtied.  There's a small race
- * window in which a writepage caller may see the page cleanness but not the
- * buffer dirtiness.  That's fine.  If this code were to set the page dirty
- * before the buffers, a concurrent writepage caller could clear the page dirty
- * bit, see a bunch of clean buffers and we'd end up with dirty buffers/clean
- * page on the dirty page list.
- *
- * There is also a small window where the page is dirty, and not on dirty_pages.
- * Also a possibility that by the time the page is added to dirty_pages, it has
- * been set clean.  The page lists are somewhat approximate in this regard.
- * It's better to have clean pages accidentally attached to dirty_pages than to
- * leave dirty pages attached to clean_pages.
- *
- * We use private_lock to lock against try_to_free_buffers while using the
- * page's buffer list.  Also use this to protect against clean buffers being
- * added to the page after it was set dirty.
- *
- * FIXME: may need to call ->reservepage here as well.  That's rather up to the
- * address_space though.
- *
- * For now, we treat swapper_space specially.  It doesn't use the normal
- * block a_ops.
- *
- * FIXME: this should move over to fs/buffer.c - buffer_heads have no business in mm/
- */
-#include <linux/buffer_head.h>
-int __set_page_dirty_buffers(struct page *page)
-{
-       struct address_space * const mapping = page->mapping;
-       int ret = 0;
-
-       if (mapping == NULL) {
-               SetPageDirty(page);
-               goto out;
-       }
-
-       if (!PageUptodate(page))
-               buffer_error();
-
-       spin_lock(&mapping->private_lock);
-       if (page_has_buffers(page)) {
-               struct buffer_head *head = page_buffers(page);
-               struct buffer_head *bh = head;
-
-               do {
-                       if (buffer_uptodate(bh))
-                               set_buffer_dirty(bh);
-                       else
-                               buffer_error();
-                       bh = bh->b_this_page;
-               } while (bh != head);
-       }
-       spin_unlock(&mapping->private_lock);
-
-       if (!TestSetPageDirty(page)) {
-               spin_lock(&mapping->page_lock);
-               if (page->mapping) {    /* Race with truncate? */
-                       if (!mapping->backing_dev_info->memory_backed)
-                               inc_page_state(nr_dirty);
-                       list_del(&page->list);
-                       list_add(&page->list, &mapping->dirty_pages);
-               }
-               spin_unlock(&mapping->page_lock);
-               __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
-       }
-       
-out:
-       return ret;
-}
-EXPORT_SYMBOL(__set_page_dirty_buffers);
-
 /*
  * For address_spaces which do not use buffers.  Just set the page's dirty bit
  * and move it to the dirty_pages list.  Also perform space reservation if