aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2011-03-23 09:27:54 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-03-23 15:29:04 -0400
commit863a3c6c686d5773f7192a4818769e15db12ce08 (patch)
tree3ff8bf04c583aa0c16ae30b0821bc9148d49a47a /fs/nfs/pnfs.c
parente0c2b3801828aadb65dec9f67f7c6b7a675ad007 (diff)
NFSv4.1: layoutcommit
The filelayout driver sends LAYOUTCOMMIT only when COMMIT goes to the data server (as opposed to the MDS) and the data server WRITE is not NFS_FILE_SYNC. Only whole file layout support means that there is only one IOMODE_RW layout segment. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Alexandros Batsakis <batsakis@netapp.com> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com> Signed-off-by: Fred Isaman <iisaman@citi.umich.edu> Signed-off-by: Mingyang Guo <guomingyang@nrchpc.ac.cn> Signed-off-by: Tao Guo <guotao@nrchpc.ac.cn> Signed-off-by: Zhang Jingwang <zhangjingwang@nrchpc.ac.cn> Tested-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index c67565965f2a..2a08ca0dddc1 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -946,3 +946,97 @@ pnfs_try_to_read_data(struct nfs_read_data *rdata,
946 dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs); 946 dprintk("%s End (trypnfs:%d)\n", __func__, trypnfs);
947 return trypnfs; 947 return trypnfs;
948} 948}
949
950/*
951 * Currently there is only one (whole file) write lseg.
952 */
953static struct pnfs_layout_segment *pnfs_list_write_lseg(struct inode *inode)
954{
955 struct pnfs_layout_segment *lseg, *rv = NULL;
956
957 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list)
958 if (lseg->pls_range.iomode == IOMODE_RW)
959 rv = lseg;
960 return rv;
961}
962
963void
964pnfs_set_layoutcommit(struct nfs_write_data *wdata)
965{
966 struct nfs_inode *nfsi = NFS_I(wdata->inode);
967 loff_t end_pos = wdata->args.offset + wdata->res.count;
968
969 spin_lock(&nfsi->vfs_inode.i_lock);
970 if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
971 /* references matched in nfs4_layoutcommit_release */
972 get_lseg(wdata->lseg);
973 wdata->lseg->pls_lc_cred =
974 get_rpccred(wdata->args.context->state->owner->so_cred);
975 mark_inode_dirty_sync(wdata->inode);
976 dprintk("%s: Set layoutcommit for inode %lu ",
977 __func__, wdata->inode->i_ino);
978 }
979 if (end_pos > wdata->lseg->pls_end_pos)
980 wdata->lseg->pls_end_pos = end_pos;
981 spin_unlock(&nfsi->vfs_inode.i_lock);
982}
983EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit);
984
985int
986pnfs_layoutcommit_inode(struct inode *inode, int sync)
987{
988 struct nfs4_layoutcommit_data *data;
989 struct nfs_inode *nfsi = NFS_I(inode);
990 struct pnfs_layout_segment *lseg;
991 struct rpc_cred *cred;
992 loff_t end_pos;
993 int status = 0;
994
995 dprintk("--> %s inode %lu\n", __func__, inode->i_ino);
996
997 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */
998 data = kzalloc(sizeof(*data), GFP_NOFS);
999 spin_lock(&inode->i_lock);
1000
1001 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
1002 spin_unlock(&inode->i_lock);
1003 kfree(data);
1004 goto out;
1005 }
1006 /*
1007 * Currently only one (whole file) write lseg which is referenced
1008 * in pnfs_set_layoutcommit and will be found.
1009 */
1010 lseg = pnfs_list_write_lseg(inode);
1011
1012 end_pos = lseg->pls_end_pos;
1013 cred = lseg->pls_lc_cred;
1014 lseg->pls_end_pos = 0;
1015 lseg->pls_lc_cred = NULL;
1016
1017 if (!data) {
1018 put_lseg(lseg);
1019 spin_unlock(&inode->i_lock);
1020 put_rpccred(cred);
1021 status = -ENOMEM;
1022 goto out;
1023 } else {
1024 memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data,
1025 sizeof(nfsi->layout->plh_stateid.data));
1026 }
1027 spin_unlock(&inode->i_lock);
1028
1029 data->args.inode = inode;
1030 data->lseg = lseg;
1031 data->cred = cred;
1032 nfs_fattr_init(&data->fattr);
1033 data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
1034 data->res.fattr = &data->fattr;
1035 data->args.lastbytewritten = end_pos - 1;
1036 data->res.server = NFS_SERVER(inode);
1037
1038 status = nfs4_proc_layoutcommit(data, sync);
1039out:
1040 dprintk("<-- %s status %d\n", __func__, status);
1041 return status;
1042}