|
@@ -42,6 +42,40 @@
|
|
|
#include <linux/pagevec.h>
|
|
|
#include <linux/writeback.h>
|
|
|
|
|
|
+
|
|
|
+/*
|
|
|
+ * Prime number of hash buckets since address is used as the key.
|
|
|
+ */
|
|
|
+#define NVSYNC 37
|
|
|
+#define to_ioend_wq(v) (&xfs_ioend_wq[((unsigned long)v) % NVSYNC])
|
|
|
+static wait_queue_head_t xfs_ioend_wq[NVSYNC];
|
|
|
+
|
|
|
+void __init
|
|
|
+xfs_ioend_init(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < NVSYNC; i++)
|
|
|
+ init_waitqueue_head(&xfs_ioend_wq[i]);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+xfs_ioend_wait(
|
|
|
+ xfs_inode_t *ip)
|
|
|
+{
|
|
|
+ wait_queue_head_t *wq = to_ioend_wq(ip);
|
|
|
+
|
|
|
+ wait_event(*wq, (atomic_read(&ip->i_iocount) == 0));
|
|
|
+}
|
|
|
+
|
|
|
+STATIC void
|
|
|
+xfs_ioend_wake(
|
|
|
+ xfs_inode_t *ip)
|
|
|
+{
|
|
|
+ if (atomic_dec_and_test(&ip->i_iocount))
|
|
|
+ wake_up(to_ioend_wq(ip));
|
|
|
+}
|
|
|
+
|
|
|
STATIC void
|
|
|
xfs_count_page_state(
|
|
|
struct page *page,
|
|
@@ -164,7 +198,7 @@ xfs_destroy_ioend(
|
|
|
__FILE__, __LINE__);
|
|
|
}
|
|
|
|
|
|
- vn_iowake(ip);
|
|
|
+ xfs_ioend_wake(ip);
|
|
|
mempool_free(ioend, xfs_ioend_pool);
|
|
|
}
|
|
|
|
|
@@ -516,7 +550,7 @@ xfs_cancel_ioend(
|
|
|
unlock_buffer(bh);
|
|
|
} while ((bh = next_bh) != NULL);
|
|
|
|
|
|
- vn_iowake(XFS_I(ioend->io_inode));
|
|
|
+ xfs_ioend_wake(XFS_I(ioend->io_inode));
|
|
|
mempool_free(ioend, xfs_ioend_pool);
|
|
|
} while ((ioend = next) != NULL);
|
|
|
}
|