Merge branch 'bugfixes' into nfs-for-2.6.38
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / nfs / dir.c
index 65d5cb4..16ec096 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/sched.h>
-#include <linux/vmalloc.h>
 #include <linux/kmemleak.h>
 #include <linux/xattr.h>
 
@@ -461,25 +460,26 @@ out:
 /* Perform conversion from xdr to cache array */
 static
 int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
-                               void *xdr_page, struct page *page, unsigned int buflen)
+                               struct page **xdr_pages, struct page *page, unsigned int buflen)
 {
        struct xdr_stream stream;
-       struct xdr_buf buf;
-       __be32 *ptr = xdr_page;
+       struct xdr_buf buf = {
+               .pages = xdr_pages,
+               .page_len = buflen,
+               .buflen = buflen,
+               .len = buflen,
+       };
+       struct page *scratch;
        struct nfs_cache_array *array;
        unsigned int count = 0;
        int status;
 
-       buf.head->iov_base = xdr_page;
-       buf.head->iov_len = buflen;
-       buf.tail->iov_len = 0;
-       buf.page_base = 0;
-       buf.page_len = 0;
-       buf.buflen = buf.head->iov_len;
-       buf.len = buf.head->iov_len;
-
-       xdr_init_decode(&stream, &buf, ptr);
+       scratch = alloc_page(GFP_KERNEL);
+       if (scratch == NULL)
+               return -ENOMEM;
 
+       xdr_init_decode(&stream, &buf, NULL);
+       xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
 
        do {
                status = xdr_decode(desc, entry, &stream);
@@ -508,6 +508,8 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
                } else
                        status = PTR_ERR(array);
        }
+
+       put_page(scratch);
        return status;
 }
 
@@ -523,7 +525,6 @@ static
 void nfs_readdir_free_large_page(void *ptr, struct page **pages,
                unsigned int npages)
 {
-       vm_unmap_ram(ptr, npages);
        nfs_readdir_free_pagearray(pages, npages);
 }
 
@@ -532,9 +533,8 @@ void nfs_readdir_free_large_page(void *ptr, struct page **pages,
  * to nfs_readdir_free_large_page
  */
 static
-void *nfs_readdir_large_page(struct page **pages, unsigned int npages)
+int nfs_readdir_large_page(struct page **pages, unsigned int npages)
 {
-       void *ptr;
        unsigned int i;
 
        for (i = 0; i < npages; i++) {
@@ -543,13 +543,11 @@ void *nfs_readdir_large_page(struct page **pages, unsigned int npages)
                        goto out_freepages;
                pages[i] = page;
        }
+       return 0;
 
-       ptr = vm_map_ram(pages, npages, 0, PAGE_KERNEL);
-       if (!IS_ERR_OR_NULL(ptr))
-               return ptr;
 out_freepages:
        nfs_readdir_free_pagearray(pages, i);
-       return NULL;
+       return -ENOMEM;
 }
 
 static
@@ -580,8 +578,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        memset(array, 0, sizeof(struct nfs_cache_array));
        array->eof_index = -1;
 
-       pages_ptr = nfs_readdir_large_page(pages, array_size);
-       if (!pages_ptr)
+       status = nfs_readdir_large_page(pages, array_size);
+       if (status < 0)
                goto out_release_array;
        do {
                unsigned int pglen;
@@ -590,7 +588,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
                if (status < 0)
                        break;
                pglen = status;
-               status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen);
+               status = nfs_readdir_page_filler(desc, &entry, pages, page, pglen);
                if (status < 0) {
                        if (status == -ENOSPC)
                                status = 0;