aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2011-03-12 02:58:09 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-03-24 15:49:48 -0400
commitde4b15c7e9fe9fdd1eb6333be0a08c822db1ca0e (patch)
tree5851c3352d20c6433677da072d2fdbc63d303b8e /fs
parentcccb4d063b263ac0713ab27d98460fda3b4f83ff (diff)
NFSv4.1 pnfs_layoutcommit_inode fixes
Test NFS_INO_LAYOUTCOMMIT before kzalloc Mark inode dirty to retry LAYOUTCOMMIT on kzalloc failure. Add comments. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/pnfs.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2a08ca0dddc1..ac7112574790 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -982,6 +982,14 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata)
982} 982}
983EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit); 983EXPORT_SYMBOL_GPL(pnfs_set_layoutcommit);
984 984
985/*
986 * For the LAYOUT4_NFSV4_1_FILES layout type, NFS_DATA_SYNC WRITEs and
987 * NFS_UNSTABLE WRITEs with a COMMIT to data servers must store enough
988 * data to disk to allow the server to recover the data if it crashes.
989 * LAYOUTCOMMIT is only needed when the NFL4_UFLG_COMMIT_THRU_MDS flag
990 * is off, and a COMMIT is sent to a data server, or
991 * if WRITEs to a data server return NFS_DATA_SYNC.
992 */
985int 993int
986pnfs_layoutcommit_inode(struct inode *inode, int sync) 994pnfs_layoutcommit_inode(struct inode *inode, int sync)
987{ 995{
@@ -994,10 +1002,18 @@ pnfs_layoutcommit_inode(struct inode *inode, int sync)
994 1002
995 dprintk("--> %s inode %lu\n", __func__, inode->i_ino); 1003 dprintk("--> %s inode %lu\n", __func__, inode->i_ino);
996 1004
1005 if (!test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
1006 return 0;
1007
997 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */ 1008 /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */
998 data = kzalloc(sizeof(*data), GFP_NOFS); 1009 data = kzalloc(sizeof(*data), GFP_NOFS);
999 spin_lock(&inode->i_lock); 1010 if (!data) {
1011 mark_inode_dirty_sync(inode);
1012 status = -ENOMEM;
1013 goto out;
1014 }
1000 1015
1016 spin_lock(&inode->i_lock);
1001 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) { 1017 if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
1002 spin_unlock(&inode->i_lock); 1018 spin_unlock(&inode->i_lock);
1003 kfree(data); 1019 kfree(data);
@@ -1014,16 +1030,8 @@ pnfs_layoutcommit_inode(struct inode *inode, int sync)
1014 lseg->pls_end_pos = 0; 1030 lseg->pls_end_pos = 0;
1015 lseg->pls_lc_cred = NULL; 1031 lseg->pls_lc_cred = NULL;
1016 1032
1017 if (!data) { 1033 memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data,
1018 put_lseg(lseg); 1034 sizeof(nfsi->layout->plh_stateid.data));
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); 1035 spin_unlock(&inode->i_lock);
1028 1036
1029 data->args.inode = inode; 1037 data->args.inode = inode;