Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44b83799 authored by Fred Isaman's avatar Fred Isaman Committed by Trond Myklebust
Browse files

NFSv4.1: trigger LAYOUTGET for writes

parent 5053aa56
Loading
Loading
Loading
Loading
+22 −0
Original line number Original line Diff line number Diff line
@@ -873,6 +873,28 @@ pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
	pgio->pg_test = (ld && ld->pg_test) ? pnfs_read_pg_test : NULL;
	pgio->pg_test = (ld && ld->pg_test) ? pnfs_read_pg_test : NULL;
}
}


static int pnfs_write_pg_test(struct nfs_pageio_descriptor *pgio,
			      struct nfs_page *prev,
			      struct nfs_page *req)
{
	if (pgio->pg_count == prev->wb_bytes) {
		/* This is first coelesce call for a series of nfs_pages */
		pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
						   prev->wb_context,
						   IOMODE_RW);
	}
	return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req);
}

void
pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode)
{
	struct pnfs_layoutdriver_type *ld;

	ld = NFS_SERVER(inode)->pnfs_curr_ld;
	pgio->pg_test = (ld && ld->pg_test) ? pnfs_write_pg_test : NULL;
}

/*
/*
 * Call the appropriate parallel I/O subsystem read function.
 * Call the appropriate parallel I/O subsystem read function.
 */
 */
+7 −0
Original line number Original line Diff line number Diff line
@@ -123,6 +123,7 @@ void unset_pnfs_layoutdriver(struct nfs_server *);
enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *,
enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *,
					    const struct rpc_call_ops *);
					    const struct rpc_call_ops *);
void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *);
int pnfs_layout_process(struct nfs4_layoutget *lgp);
int pnfs_layout_process(struct nfs4_layoutget *lgp);
void pnfs_free_lseg_list(struct list_head *tmp_list);
void pnfs_free_lseg_list(struct list_head *tmp_list);
void pnfs_destroy_layout(struct nfs_inode *);
void pnfs_destroy_layout(struct nfs_inode *);
@@ -235,6 +236,12 @@ pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino)
	pgio->pg_test = NULL;
	pgio->pg_test = NULL;
}
}


static inline void
pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino)
{
	pgio->pg_test = NULL;
}

#endif /* CONFIG_NFS_V4_1 */
#endif /* CONFIG_NFS_V4_1 */


#endif /* FS_NFS_PNFS_H */
#endif /* FS_NFS_PNFS_H */
+20 −12
Original line number Original line Diff line number Diff line
@@ -919,6 +919,8 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
	} while (nbytes != 0);
	} while (nbytes != 0);
	atomic_set(&req->wb_complete, requests);
	atomic_set(&req->wb_complete, requests);


	BUG_ON(lseg);
	lseg = pnfs_update_layout(inode, req->wb_context, IOMODE_RW);
	ClearPageError(page);
	ClearPageError(page);
	offset = 0;
	offset = 0;
	nbytes = count;
	nbytes = count;
@@ -940,6 +942,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
		nbytes -= wsize;
		nbytes -= wsize;
	} while (nbytes != 0);
	} while (nbytes != 0);


	put_lseg(lseg);
	return ret;
	return ret;


out_bad:
out_bad:
@@ -965,11 +968,18 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
	struct nfs_page		*req;
	struct nfs_page		*req;
	struct page		**pages;
	struct page		**pages;
	struct nfs_write_data	*data;
	struct nfs_write_data	*data;
	int ret;


	data = nfs_writedata_alloc(npages);
	data = nfs_writedata_alloc(npages);
	if (!data)
	if (!data) {
		goto out_bad;
		while (!list_empty(head)) {

			req = nfs_list_entry(head->next);
			nfs_list_remove_request(req);
			nfs_redirty_request(req);
		}
		ret = -ENOMEM;
		goto out;
	}
	pages = data->pagevec;
	pages = data->pagevec;
	while (!list_empty(head)) {
	while (!list_empty(head)) {
		req = nfs_list_entry(head->next);
		req = nfs_list_entry(head->next);
@@ -979,16 +989,14 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
		*pages++ = req->wb_page;
		*pages++ = req->wb_page;
	}
	}
	req = nfs_list_entry(data->pages.next);
	req = nfs_list_entry(data->pages.next);
	if ((!lseg) && list_is_singular(&data->pages))
		lseg = pnfs_update_layout(inode, req->wb_context, IOMODE_RW);


	/* Set up the argument struct */
	/* Set up the argument struct */
	return nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, lseg, how);
	ret = nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, lseg, how);
 out_bad:
out:
	while (!list_empty(head)) {
	put_lseg(lseg); /* Cleans any gotten in ->pg_test */
		req = nfs_list_entry(head->next);
	return ret;
		nfs_list_remove_request(req);
		nfs_redirty_request(req);
	}
	return -ENOMEM;
}
}


static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
@@ -996,7 +1004,7 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
{
{
	size_t wsize = NFS_SERVER(inode)->wsize;
	size_t wsize = NFS_SERVER(inode)->wsize;


	pgio->pg_test = NULL;
	pnfs_pageio_init_write(pgio, inode);


	if (wsize < PAGE_CACHE_SIZE)
	if (wsize < PAGE_CACHE_SIZE)
		nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags);
		nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags);