|
@@ -57,6 +57,7 @@
|
|
#define NFSDBG_FACILITY NFSDBG_VFS
|
|
#define NFSDBG_FACILITY NFSDBG_VFS
|
|
#define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT)
|
|
#define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT)
|
|
|
|
|
|
|
|
+static void nfs_free_user_pages(struct page **pages, int npages, int do_dirty);
|
|
static kmem_cache_t *nfs_direct_cachep;
|
|
static kmem_cache_t *nfs_direct_cachep;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -107,6 +108,15 @@ nfs_get_user_pages(int rw, unsigned long user_addr, size_t size,
|
|
page_count, (rw == READ), 0,
|
|
page_count, (rw == READ), 0,
|
|
*pages, NULL);
|
|
*pages, NULL);
|
|
up_read(¤t->mm->mmap_sem);
|
|
up_read(¤t->mm->mmap_sem);
|
|
|
|
+ /*
|
|
|
|
+ * If we got fewer pages than expected from get_user_pages(),
|
|
|
|
+ * the user buffer runs off the end of a mapping; return EFAULT.
|
|
|
|
+ */
|
|
|
|
+ if (result >= 0 && result < page_count) {
|
|
|
|
+ nfs_free_user_pages(*pages, result, 0);
|
|
|
|
+ *pages = NULL;
|
|
|
|
+ result = -EFAULT;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|