Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
[sfrench/cifs-2.6.git] / fs / xfs / linux-2.6 / xfs_buf.c
index e44b7c1a3a36d432617edfd66131c30a259359f9..9fb0312665caacd41872527e101f8c19706ceaa1 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/blkdev.h>
 #include <linux/hash.h>
 #include <linux/kthread.h>
+#include <linux/migrate.h>
 #include "xfs_linux.h"
 
 STATIC kmem_zone_t *xfs_buf_zone;
@@ -822,6 +823,13 @@ xfs_buf_rele(
 
        XB_TRACE(bp, "rele", bp->b_relse);
 
+       if (unlikely(!hash)) {
+               ASSERT(!bp->b_relse);
+               if (atomic_dec_and_test(&bp->b_hold))
+                       xfs_buf_free(bp);
+               return;
+       }
+
        if (atomic_dec_and_lock(&bp->b_hold, &hash->bh_lock)) {
                if (bp->b_relse) {
                        atomic_inc(&bp->b_hold);
@@ -1514,6 +1522,7 @@ xfs_mapping_buftarg(
        struct address_space    *mapping;
        static struct address_space_operations mapping_aops = {
                .sync_page = block_sync_page,
+               .migratepage = fail_migrate_page,
        };
 
        inode = new_inode(bdev->bd_inode->i_sb);
@@ -1797,13 +1806,12 @@ xfs_flush_buftarg(
 int __init
 xfs_buf_init(void)
 {
-       int             error = -ENOMEM;
-
 #ifdef XFS_BUF_TRACE
        xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP);
 #endif
 
-       xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
+       xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf",
+                                               KM_ZONE_HWALIGN, NULL);
        if (!xfs_buf_zone)
                goto out_free_trace_buf;
 
@@ -1831,7 +1839,7 @@ xfs_buf_init(void)
 #ifdef XFS_BUF_TRACE
        ktrace_free(xfs_buf_trace_buf);
 #endif
-       return error;
+       return -ENOMEM;
 }
 
 void