]> err.no Git - linux-2.6/blobdiff - fs/nfs/pagelist.c
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[linux-2.6] / fs / nfs / pagelist.c
index e12054c86d0dd349dd0750e4dd92e44c6f2e9399..c5bb51a29e8072198c57963f5c3c9dbf86ebc6ab 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/slab.h>
 #include <linux/file.h>
+#include <linux/sched.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs3.h>
 #include <linux/nfs4.h>
@@ -354,6 +355,26 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
        nfs_pageio_doio(desc);
 }
 
+/**
+ * nfs_pageio_cond_complete - Conditional I/O completion
+ * @desc: pointer to io descriptor
+ * @index: page index
+ *
+ * It is important to ensure that processes don't try to take locks
+ * on non-contiguous ranges of pages as that might deadlock. This
+ * function should be called before attempting to wait on a locked
+ * nfs_page. It will complete the I/O if the page index 'index'
+ * is not contiguous with the existing list of pages in 'desc'.
+ */
+void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
+{
+       if (!list_empty(&desc->pg_list)) {
+               struct nfs_page *prev = nfs_list_entry(desc->pg_list.prev);
+               if (index != prev->wb_index + 1)
+                       nfs_pageio_doio(desc);
+       }
+}
+
 #define NFS_SCAN_MAXENTRIES 16
 /**
  * nfs_scan_list - Scan a list for matching requests