summaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-07-21 12:44:15 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-07-24 16:16:39 -0400
commite5fd1904b8422615a2a286777e2b7c881ad53e73 (patch)
treec487abdf11e5502658827c2973a845f9be021607 /fs/nfs/pnfs.c
parent793b7fe55858dca1f5bd3e42185b541a9eddc144 (diff)
pNFS: Ensure layoutreturn acts as a completion for layout callbacks
When we return NFS_OK to the CB_LAYOUTRECALL, we are required to send a layoutreturn that "completes" that layout recall request, using the correct stateid. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 85c3e7b47ddb..878dc4b7085a 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -883,12 +883,28 @@ pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo)
883} 883}
884 884
885static bool 885static bool
886pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo) 886pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
887 nfs4_stateid *stateid,
888 enum pnfs_iomode *iomode)
887{ 889{
888 if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) 890 if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
889 return false; 891 return false;
890 pnfs_get_layout_hdr(lo); 892 pnfs_get_layout_hdr(lo);
891 pnfs_clear_layoutreturn_info(lo); 893 if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) {
894 if (stateid != NULL) {
895 nfs4_stateid_copy(stateid, &lo->plh_stateid);
896 if (lo->plh_return_seq != 0)
897 stateid->seqid = cpu_to_be32(lo->plh_return_seq);
898 }
899 if (iomode != NULL)
900 *iomode = lo->plh_return_iomode;
901 pnfs_clear_layoutreturn_info(lo);
902 return true;
903 }
904 if (stateid != NULL)
905 nfs4_stateid_copy(stateid, &lo->plh_stateid);
906 if (iomode != NULL)
907 *iomode = IOMODE_ANY;
892 return true; 908 return true;
893} 909}
894 910
@@ -956,10 +972,7 @@ static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo)
956 enum pnfs_iomode iomode; 972 enum pnfs_iomode iomode;
957 bool send; 973 bool send;
958 974
959 nfs4_stateid_copy(&stateid, &lo->plh_stateid); 975 send = pnfs_prepare_layoutreturn(lo, &stateid, &iomode);
960 stateid.seqid = cpu_to_be32(lo->plh_return_seq);
961 iomode = lo->plh_return_iomode;
962 send = pnfs_prepare_layoutreturn(lo);
963 spin_unlock(&inode->i_lock); 976 spin_unlock(&inode->i_lock);
964 if (send) { 977 if (send) {
965 /* Send an async layoutreturn so we dont deadlock */ 978 /* Send an async layoutreturn so we dont deadlock */
@@ -996,7 +1009,6 @@ _pnfs_return_layout(struct inode *ino)
996 dprintk("NFS: %s no layout to return\n", __func__); 1009 dprintk("NFS: %s no layout to return\n", __func__);
997 goto out; 1010 goto out;
998 } 1011 }
999 nfs4_stateid_copy(&stateid, &nfsi->layout->plh_stateid);
1000 /* Reference matched in nfs4_layoutreturn_release */ 1012 /* Reference matched in nfs4_layoutreturn_release */
1001 pnfs_get_layout_hdr(lo); 1013 pnfs_get_layout_hdr(lo);
1002 empty = list_empty(&lo->plh_segs); 1014 empty = list_empty(&lo->plh_segs);
@@ -1020,7 +1032,7 @@ _pnfs_return_layout(struct inode *ino)
1020 } 1032 }
1021 1033
1022 set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); 1034 set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
1023 send = pnfs_prepare_layoutreturn(lo); 1035 send = pnfs_prepare_layoutreturn(lo, &stateid, NULL);
1024 spin_unlock(&ino->i_lock); 1036 spin_unlock(&ino->i_lock);
1025 pnfs_free_lseg_list(&tmp_list); 1037 pnfs_free_lseg_list(&tmp_list);
1026 if (send) 1038 if (send)
@@ -1087,11 +1099,10 @@ bool pnfs_roc(struct inode *ino)
1087 goto out_noroc; 1099 goto out_noroc;
1088 } 1100 }
1089 1101
1090 nfs4_stateid_copy(&stateid, &lo->plh_stateid);
1091 /* always send layoutreturn if being marked so */ 1102 /* always send layoutreturn if being marked so */
1092 if (test_and_clear_bit(NFS_LAYOUT_RETURN_REQUESTED, 1103 if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
1093 &lo->plh_flags)) 1104 layoutreturn = pnfs_prepare_layoutreturn(lo,
1094 layoutreturn = pnfs_prepare_layoutreturn(lo); 1105 &stateid, NULL);
1095 1106
1096 list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list) 1107 list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list)
1097 /* If we are sending layoutreturn, invalidate all valid lsegs */ 1108 /* If we are sending layoutreturn, invalidate all valid lsegs */
@@ -1874,10 +1885,9 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
1874 if (!pnfs_mark_matching_lsegs_return(lo, &free_me, 1885 if (!pnfs_mark_matching_lsegs_return(lo, &free_me,
1875 &range, lseg->pls_seq)) { 1886 &range, lseg->pls_seq)) {
1876 nfs4_stateid stateid; 1887 nfs4_stateid stateid;
1877 enum pnfs_iomode iomode = lo->plh_return_iomode; 1888 enum pnfs_iomode iomode;
1878 1889
1879 nfs4_stateid_copy(&stateid, &lo->plh_stateid); 1890 return_now = pnfs_prepare_layoutreturn(lo, &stateid, &iomode);
1880 return_now = pnfs_prepare_layoutreturn(lo);
1881 spin_unlock(&inode->i_lock); 1891 spin_unlock(&inode->i_lock);
1882 if (return_now) 1892 if (return_now)
1883 pnfs_send_layoutreturn(lo, &stateid, iomode, false); 1893 pnfs_send_layoutreturn(lo, &stateid, iomode, false);