@@ -46,6 +46,11 @@ static DEFINE_SPINLOCK(pnfs_spinlock);
*/
static LIST_HEAD(pnfs_modules_tbl);
+/*
+ * layoutget prefetch size
+ */
+unsigned int pnfs_layout_prefetch_kb;
+
/* Return the registered pnfs layout driver module matching given id */
static struct pnfs_layoutdriver_type *
find_pnfs_driver_locked(u32 id)
@@ -909,6 +914,16 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
}
/*
+ * Set layout prefetch length.
+ */
+static void
+pnfs_set_layout_prefetch(struct pnfs_layout_range *range)
+{
+ if (range->length < (pnfs_layout_prefetch_kb << 10))
+ range->length = pnfs_layout_prefetch_kb << 10;
+}
+
+/*
* Layout segment is retreived from the server if not cached.
* The appropriate layout segment is referenced and returned to the caller.
*/
@@ -959,6 +974,8 @@ pnfs_update_layout(struct inode *ino,
if (pnfs_layoutgets_blocked(lo, NULL, 0))
goto out_unlock;
+
+ pnfs_set_layout_prefetch(&arg);
atomic_inc(&lo->plh_outstanding);
get_layout_hdr(lo);
@@ -180,6 +180,7 @@ extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
/* pnfs.c */
+extern unsigned int pnfs_layout_prefetch_kb;
void get_layout_hdr(struct pnfs_layout_hdr *lo);
void put_lseg(struct pnfs_layout_segment *lseg);
@@ -14,6 +14,7 @@
#include <linux/nfs_fs.h>
#include "callback.h"
+#include "pnfs.h"
#ifdef CONFIG_NFS_V4
static const int nfs_set_port_min = 0;
@@ -42,6 +43,15 @@ static ctl_table nfs_cb_sysctls[] = {
},
#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
#endif
+#ifdef CONFIG_NFS_V4_1
+ {
+ .procname = "pnfs_layout_prefetch_kb",
+ .data = &pnfs_layout_prefetch_kb,
+ .maxlen = sizeof(pnfs_layout_prefetch_kb),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+#endif
{
.procname = "nfs_mountpoint_timeout",
.data = &nfs_mountpoint_expiry_timeout,