aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-08-06 22:15:02 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-09-10 15:47:00 -0400
commit378520b837cf4da769600b83690d8e825f16a611 (patch)
treeb2561ec480dbfb3e5b481a64aa5ba031d86d04b1 /fs/nfs
parent61beef75cc5bae119e500c9f25daad8596c7cbe4 (diff)
nfs41: add a helper function to set layoutcommit after commit
Track lwb in nfs_commit_data so that we can use it to setup layoutcommit in commit_done callback. Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/pnfs.c29
-rw-r--r--fs/nfs/pnfs.h1
-rw-r--r--fs/nfs/write.c15
3 files changed, 45 insertions, 0 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index a3851debf8a2..a6586cdee211 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1797,6 +1797,35 @@ pnfs_set_layoutcommit(struct nfs_pgio_header *hdr)
1797} 1797}
1798EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit); 1798EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit);
1799 1799
1800void pnfs_commit_set_layoutcommit(struct nfs_commit_data *data)
1801{
1802 struct inode *inode = data->inode;
1803 struct nfs_inode *nfsi = NFS_I(inode);
1804 bool mark_as_dirty = false;
1805
1806 spin_lock(&inode->i_lock);
1807 if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
1808 mark_as_dirty = true;
1809 dprintk("%s: Set layoutcommit for inode %lu ",
1810 __func__, inode->i_ino);
1811 }
1812 if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &data->lseg->pls_flags)) {
1813 /* references matched in nfs4_layoutcommit_release */
1814 pnfs_get_lseg(data->lseg);
1815 }
1816 if (data->lwb > nfsi->layout->plh_lwb)
1817 nfsi->layout->plh_lwb = data->lwb;
1818 spin_unlock(&inode->i_lock);
1819 dprintk("%s: lseg %p end_pos %llu\n",
1820 __func__, data->lseg, nfsi->layout->plh_lwb);
1821
1822 /* if pnfs_layoutcommit_inode() runs between inode locks, the next one
1823 * will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */
1824 if (mark_as_dirty)
1825 mark_inode_dirty_sync(inode);
1826}
1827EXPORT_SYMBOL_GPL(pnfs_commit_set_layoutcommit);
1828
1800void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data) 1829void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data)
1801{ 1830{
1802 struct nfs_server *nfss = NFS_SERVER(data->args.inode); 1831 struct nfs_server *nfss = NFS_SERVER(data->args.inode);
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index aca3dff5dae6..79c63114ce77 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -219,6 +219,7 @@ void pnfs_roc_release(struct inode *ino);
219void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); 219void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);
220bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task); 220bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task);
221void pnfs_set_layoutcommit(struct nfs_pgio_header *); 221void pnfs_set_layoutcommit(struct nfs_pgio_header *);
222void pnfs_commit_set_layoutcommit(struct nfs_commit_data *data);
222void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data); 223void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
223int pnfs_layoutcommit_inode(struct inode *inode, bool sync); 224int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
224int _pnfs_return_layout(struct inode *); 225int _pnfs_return_layout(struct inode *);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 175d5d073ccf..3c5638f381cd 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1538,6 +1538,18 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
1538} 1538}
1539EXPORT_SYMBOL_GPL(nfs_initiate_commit); 1539EXPORT_SYMBOL_GPL(nfs_initiate_commit);
1540 1540
1541static loff_t nfs_get_lwb(struct list_head *head)
1542{
1543 loff_t lwb = 0;
1544 struct nfs_page *req;
1545
1546 list_for_each_entry(req, head, wb_list)
1547 if (lwb < (req_offset(req) + req->wb_bytes))
1548 lwb = req_offset(req) + req->wb_bytes;
1549
1550 return lwb;
1551}
1552
1541/* 1553/*
1542 * Set up the argument/result storage required for the RPC call. 1554 * Set up the argument/result storage required for the RPC call.
1543 */ 1555 */
@@ -1557,6 +1569,9 @@ void nfs_init_commit(struct nfs_commit_data *data,
1557 data->inode = inode; 1569 data->inode = inode;
1558 data->cred = first->wb_context->cred; 1570 data->cred = first->wb_context->cred;
1559 data->lseg = lseg; /* reference transferred */ 1571 data->lseg = lseg; /* reference transferred */
1572 /* only set lwb for pnfs commit */
1573 if (lseg)
1574 data->lwb = nfs_get_lwb(&data->pages);
1560 data->mds_ops = &nfs_commit_ops; 1575 data->mds_ops = &nfs_commit_ops;
1561 data->completion_ops = cinfo->completion_ops; 1576 data->completion_ops = cinfo->completion_ops;
1562 data->dreq = cinfo->dreq; 1577 data->dreq = cinfo->dreq;