Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / fs / buffer.c
index 7f6d659..9f27576 100644 (file)
@@ -18,7 +18,6 @@
  * async buffer flushing, 1999 Andrea Arcangeli <andrea@suse.de>
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/syscalls.h>
 #include <linux/fs.h>
@@ -185,6 +184,8 @@ int fsync_super(struct super_block *sb)
        return sync_blockdev(sb->s_bdev);
 }
 
+EXPORT_SYMBOL(fsync_super);
+
 /*
  * Write out and wait upon all dirty data associated with this
  * device.   Filesystem data as well as the underlying block
@@ -331,7 +332,6 @@ long do_fsync(struct file *file, int datasync)
                goto out;
        }
 
-       current->flags |= PF_SYNCWRITE;
        ret = filemap_fdatawrite(mapping);
 
        /*
@@ -346,7 +346,6 @@ long do_fsync(struct file *file, int datasync)
        err = filemap_fdatawait(mapping);
        if (!ret)
                ret = err;
-       current->flags &= ~PF_SYNCWRITE;
 out:
        return ret;
 }
@@ -571,7 +570,7 @@ still_busy:
  * Completion handler for block_write_full_page() - pages which are unlocked
  * during I/O, and which have PageWriteback cleared upon I/O completion.
  */
-void end_buffer_async_write(struct buffer_head *bh, int uptodate)
+static void end_buffer_async_write(struct buffer_head *bh, int uptodate)
 {
        char b[BDEVNAME_SIZE];
        unsigned long flags;
@@ -841,7 +840,10 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
  */
 int __set_page_dirty_buffers(struct page *page)
 {
-       struct address_space * const mapping = page->mapping;
+       struct address_space * const mapping = page_mapping(page);
+
+       if (unlikely(!mapping))
+               return !TestSetPageDirty(page);
 
        spin_lock(&mapping->private_lock);
        if (page_has_buffers(page)) {
@@ -859,7 +861,7 @@ int __set_page_dirty_buffers(struct page *page)
                write_lock_irq(&mapping->tree_lock);
                if (page->mapping) {    /* Race with truncate? */
                        if (mapping_cap_account_dirty(mapping))
-                               inc_page_state(nr_dirty);
+                               __inc_zone_page_state(page, NR_FILE_DIRTY);
                        radix_tree_tag_set(&mapping->page_tree,
                                                page_index(page),
                                                PAGECACHE_TAG_DIRTY);
@@ -2605,7 +2607,7 @@ int nobh_truncate_page(struct address_space *mapping, loff_t from)
        unsigned offset = from & (PAGE_CACHE_SIZE-1);
        unsigned to;
        struct page *page;
-       struct address_space_operations *a_ops = mapping->a_ops;
+       const struct address_space_operations *a_ops = mapping->a_ops;
        char *kaddr;
        int ret = 0;
 
@@ -2990,6 +2992,7 @@ int try_to_free_buffers(struct page *page)
 
        spin_lock(&mapping->private_lock);
        ret = drop_buffers(page, &buffers_to_free);
+       spin_unlock(&mapping->private_lock);
        if (ret) {
                /*
                 * If the filesystem writes its buffers by hand (eg ext3)
@@ -3001,7 +3004,6 @@ int try_to_free_buffers(struct page *page)
                 */
                clear_page_dirty(page);
        }
-       spin_unlock(&mapping->private_lock);
 out:
        if (buffers_to_free) {
                struct buffer_head *bh = buffers_to_free;
@@ -3173,7 +3175,6 @@ EXPORT_SYMBOL(block_sync_page);
 EXPORT_SYMBOL(block_truncate_page);
 EXPORT_SYMBOL(block_write_full_page);
 EXPORT_SYMBOL(cont_prepare_write);
-EXPORT_SYMBOL(end_buffer_async_write);
 EXPORT_SYMBOL(end_buffer_read_sync);
 EXPORT_SYMBOL(end_buffer_write_sync);
 EXPORT_SYMBOL(file_fsync);