@@ -324,6 +324,21 @@ pnfs_grab_inode_layout_hdr(struct pnfs_layout_hdr *lo)
324324 return NULL ;
325325}
326326
327+ /*
328+ * Compare 2 layout stateid sequence ids, to see which is newer,
329+ * taking into account wraparound issues.
330+ */
331+ static bool pnfs_seqid_is_newer (u32 s1 , u32 s2 )
332+ {
333+ return (s32 )(s1 - s2 ) > 0 ;
334+ }
335+
336+ static void pnfs_barrier_update (struct pnfs_layout_hdr * lo , u32 newseq )
337+ {
338+ if (pnfs_seqid_is_newer (newseq , lo -> plh_barrier ))
339+ lo -> plh_barrier = newseq ;
340+ }
341+
327342static void
328343pnfs_set_plh_return_info (struct pnfs_layout_hdr * lo , enum pnfs_iomode iomode ,
329344 u32 seq )
@@ -335,6 +350,7 @@ pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode,
335350 if (seq != 0 ) {
336351 WARN_ON_ONCE (lo -> plh_return_seq != 0 && lo -> plh_return_seq != seq );
337352 lo -> plh_return_seq = seq ;
353+ pnfs_barrier_update (lo , seq );
338354 }
339355}
340356
@@ -639,15 +655,6 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
639655 return rv ;
640656}
641657
642- /*
643- * Compare 2 layout stateid sequence ids, to see which is newer,
644- * taking into account wraparound issues.
645- */
646- static bool pnfs_seqid_is_newer (u32 s1 , u32 s2 )
647- {
648- return (s32 )(s1 - s2 ) > 0 ;
649- }
650-
651658static bool
652659pnfs_should_free_range (const struct pnfs_layout_range * lseg_range ,
653660 const struct pnfs_layout_range * recall_range )
@@ -984,8 +991,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
984991 new_barrier = be32_to_cpu (new -> seqid );
985992 else if (new_barrier == 0 )
986993 return ;
987- if (pnfs_seqid_is_newer (new_barrier , lo -> plh_barrier ))
988- lo -> plh_barrier = new_barrier ;
994+ pnfs_barrier_update (lo , new_barrier );
989995}
990996
991997static bool
@@ -994,7 +1000,7 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
9941000{
9951001 u32 seqid = be32_to_cpu (stateid -> seqid );
9961002
997- return !pnfs_seqid_is_newer (seqid , lo -> plh_barrier );
1003+ return !pnfs_seqid_is_newer (seqid , lo -> plh_barrier ) && lo -> plh_barrier ;
9981004}
9991005
10001006/* lget is set to 1 if called from inside send_layoutget call chain */
@@ -1183,20 +1189,17 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
11831189 return false;
11841190 set_bit (NFS_LAYOUT_RETURN , & lo -> plh_flags );
11851191 pnfs_get_layout_hdr (lo );
1192+ nfs4_stateid_copy (stateid , & lo -> plh_stateid );
1193+ * cred = get_cred (lo -> plh_lc_cred );
11861194 if (test_bit (NFS_LAYOUT_RETURN_REQUESTED , & lo -> plh_flags )) {
1187- nfs4_stateid_copy (stateid , & lo -> plh_stateid );
1188- * cred = get_cred (lo -> plh_lc_cred );
11891195 if (lo -> plh_return_seq != 0 )
11901196 stateid -> seqid = cpu_to_be32 (lo -> plh_return_seq );
11911197 if (iomode != NULL )
11921198 * iomode = lo -> plh_return_iomode ;
11931199 pnfs_clear_layoutreturn_info (lo );
1194- return true;
1195- }
1196- nfs4_stateid_copy (stateid , & lo -> plh_stateid );
1197- * cred = get_cred (lo -> plh_lc_cred );
1198- if (iomode != NULL )
1200+ } else if (iomode != NULL )
11991201 * iomode = IOMODE_ANY ;
1202+ pnfs_barrier_update (lo , be32_to_cpu (stateid -> seqid ));
12001203 return true;
12011204}
12021205
@@ -1909,6 +1912,11 @@ static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
19091912 wake_up_var (& lo -> plh_outstanding );
19101913}
19111914
1915+ static bool pnfs_is_first_layoutget (struct pnfs_layout_hdr * lo )
1916+ {
1917+ return test_bit (NFS_LAYOUT_FIRST_LAYOUTGET , & lo -> plh_flags );
1918+ }
1919+
19121920static void pnfs_clear_first_layoutget (struct pnfs_layout_hdr * lo )
19131921{
19141922 unsigned long * bitlock = & lo -> plh_flags ;
@@ -2383,23 +2391,34 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
23832391 goto out_forget ;
23842392 }
23852393
2386- if (!pnfs_layout_is_valid (lo )) {
2387- /* We have a completely new layout */
2388- pnfs_set_layout_stateid (lo , & res -> stateid , lgp -> cred , true);
2389- } else if (nfs4_stateid_match_other (& lo -> plh_stateid , & res -> stateid )) {
2394+ if (nfs4_stateid_match_other (& lo -> plh_stateid , & res -> stateid )) {
23902395 /* existing state ID, make sure the sequence number matches. */
23912396 if (pnfs_layout_stateid_blocked (lo , & res -> stateid )) {
2397+ if (!pnfs_layout_is_valid (lo ) &&
2398+ pnfs_is_first_layoutget (lo ))
2399+ lo -> plh_barrier = 0 ;
23922400 dprintk ("%s forget reply due to sequence\n" , __func__ );
23932401 goto out_forget ;
23942402 }
23952403 pnfs_set_layout_stateid (lo , & res -> stateid , lgp -> cred , false);
2396- } else {
2404+ } else if ( pnfs_layout_is_valid ( lo )) {
23972405 /*
23982406 * We got an entirely new state ID. Mark all segments for the
23992407 * inode invalid, and retry the layoutget
24002408 */
2401- pnfs_mark_layout_stateid_invalid (lo , & free_me );
2409+ struct pnfs_layout_range range = {
2410+ .iomode = IOMODE_ANY ,
2411+ .length = NFS4_MAX_UINT64 ,
2412+ };
2413+ pnfs_set_plh_return_info (lo , IOMODE_ANY , 0 );
2414+ pnfs_mark_matching_lsegs_return (lo , & lo -> plh_return_segs ,
2415+ & range , 0 );
24022416 goto out_forget ;
2417+ } else {
2418+ /* We have a completely new layout */
2419+ if (!pnfs_is_first_layoutget (lo ))
2420+ goto out_forget ;
2421+ pnfs_set_layout_stateid (lo , & res -> stateid , lgp -> cred , true);
24032422 }
24042423
24052424 pnfs_get_lseg (lseg );
0 commit comments