@@ -52,9 +52,7 @@ static DEFINE_SPINLOCK(pnfs_spinlock);
52
52
*/
53
53
static LIST_HEAD (pnfs_modules_tbl );
54
54
55
- static int
56
- pnfs_send_layoutreturn (struct pnfs_layout_hdr * lo , const nfs4_stateid * stateid ,
57
- enum pnfs_iomode iomode , bool sync );
55
+ static void pnfs_layoutreturn_before_put_layout_hdr (struct pnfs_layout_hdr * lo );
58
56
59
57
/* Return the registered pnfs layout driver module matching given id */
60
58
static struct pnfs_layoutdriver_type *
@@ -243,6 +241,8 @@ pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
243
241
{
244
242
struct inode * inode = lo -> plh_inode ;
245
243
244
+ pnfs_layoutreturn_before_put_layout_hdr (lo );
245
+
246
246
if (atomic_dec_and_lock (& lo -> plh_refcount , & inode -> i_lock )) {
247
247
if (!list_empty (& lo -> plh_segs ))
248
248
WARN_ONCE (1 , "NFS: BUG unfreed layout segments.\n" );
@@ -345,58 +345,6 @@ pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo,
345
345
rpc_wake_up (& NFS_SERVER (inode )-> roc_rpcwaitq );
346
346
}
347
347
348
- /* Return true if layoutreturn is needed */
349
- static bool
350
- pnfs_layout_need_return (struct pnfs_layout_hdr * lo ,
351
- struct pnfs_layout_segment * lseg )
352
- {
353
- struct pnfs_layout_segment * s ;
354
-
355
- if (!test_and_clear_bit (NFS_LSEG_LAYOUTRETURN , & lseg -> pls_flags ))
356
- return false;
357
-
358
- list_for_each_entry (s , & lo -> plh_segs , pls_list )
359
- if (s != lseg && test_bit (NFS_LSEG_LAYOUTRETURN , & s -> pls_flags ))
360
- return false;
361
-
362
- return true;
363
- }
364
-
365
- static bool
366
- pnfs_prepare_layoutreturn (struct pnfs_layout_hdr * lo )
367
- {
368
- if (test_and_set_bit (NFS_LAYOUT_RETURN , & lo -> plh_flags ))
369
- return false;
370
- lo -> plh_return_iomode = 0 ;
371
- pnfs_get_layout_hdr (lo );
372
- clear_bit (NFS_LAYOUT_RETURN_BEFORE_CLOSE , & lo -> plh_flags );
373
- return true;
374
- }
375
-
376
- static void pnfs_layoutreturn_before_put_lseg (struct pnfs_layout_segment * lseg ,
377
- struct pnfs_layout_hdr * lo , struct inode * inode )
378
- {
379
- lo = lseg -> pls_layout ;
380
- inode = lo -> plh_inode ;
381
-
382
- spin_lock (& inode -> i_lock );
383
- if (pnfs_layout_need_return (lo , lseg )) {
384
- nfs4_stateid stateid ;
385
- enum pnfs_iomode iomode ;
386
- bool send ;
387
-
388
- nfs4_stateid_copy (& stateid , & lo -> plh_stateid );
389
- iomode = lo -> plh_return_iomode ;
390
- send = pnfs_prepare_layoutreturn (lo );
391
- spin_unlock (& inode -> i_lock );
392
- if (send ) {
393
- /* Send an async layoutreturn so we dont deadlock */
394
- pnfs_send_layoutreturn (lo , & stateid , iomode , false);
395
- }
396
- } else
397
- spin_unlock (& inode -> i_lock );
398
- }
399
-
400
348
void
401
349
pnfs_put_lseg (struct pnfs_layout_segment * lseg )
402
350
{
@@ -410,15 +358,8 @@ pnfs_put_lseg(struct pnfs_layout_segment *lseg)
410
358
atomic_read (& lseg -> pls_refcount ),
411
359
test_bit (NFS_LSEG_VALID , & lseg -> pls_flags ));
412
360
413
- /* Handle the case where refcount != 1 */
414
- if (atomic_add_unless (& lseg -> pls_refcount , -1 , 1 ))
415
- return ;
416
-
417
361
lo = lseg -> pls_layout ;
418
362
inode = lo -> plh_inode ;
419
- /* Do we need a layoutreturn? */
420
- if (test_bit (NFS_LSEG_LAYOUTRETURN , & lseg -> pls_flags ))
421
- pnfs_layoutreturn_before_put_lseg (lseg , lo , inode );
422
363
423
364
if (atomic_dec_and_lock (& lseg -> pls_refcount , & inode -> i_lock )) {
424
365
if (test_bit (NFS_LSEG_VALID , & lseg -> pls_flags )) {
@@ -937,6 +878,17 @@ void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
937
878
rpc_wake_up (& NFS_SERVER (lo -> plh_inode )-> roc_rpcwaitq );
938
879
}
939
880
881
+ static bool
882
+ pnfs_prepare_layoutreturn (struct pnfs_layout_hdr * lo )
883
+ {
884
+ if (test_and_set_bit (NFS_LAYOUT_RETURN , & lo -> plh_flags ))
885
+ return false;
886
+ lo -> plh_return_iomode = 0 ;
887
+ pnfs_get_layout_hdr (lo );
888
+ clear_bit (NFS_LAYOUT_RETURN_REQUESTED , & lo -> plh_flags );
889
+ return true;
890
+ }
891
+
940
892
static int
941
893
pnfs_send_layoutreturn (struct pnfs_layout_hdr * lo , const nfs4_stateid * stateid ,
942
894
enum pnfs_iomode iomode , bool sync )
@@ -971,6 +923,48 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, const nfs4_stateid *stateid,
971
923
return status ;
972
924
}
973
925
926
+ /* Return true if layoutreturn is needed */
927
+ static bool
928
+ pnfs_layout_need_return (struct pnfs_layout_hdr * lo )
929
+ {
930
+ struct pnfs_layout_segment * s ;
931
+
932
+ if (!test_bit (NFS_LAYOUT_RETURN_REQUESTED , & lo -> plh_flags ))
933
+ return false;
934
+
935
+ /* Defer layoutreturn until all lsegs are done */
936
+ list_for_each_entry (s , & lo -> plh_segs , pls_list ) {
937
+ if (test_bit (NFS_LSEG_LAYOUTRETURN , & s -> pls_flags ))
938
+ return false;
939
+ }
940
+
941
+ return true;
942
+ }
943
+
944
+ static void pnfs_layoutreturn_before_put_layout_hdr (struct pnfs_layout_hdr * lo )
945
+ {
946
+ struct inode * inode = lo -> plh_inode ;
947
+
948
+ if (!test_bit (NFS_LAYOUT_RETURN_REQUESTED , & lo -> plh_flags ))
949
+ return ;
950
+ spin_lock (& inode -> i_lock );
951
+ if (pnfs_layout_need_return (lo )) {
952
+ nfs4_stateid stateid ;
953
+ enum pnfs_iomode iomode ;
954
+ bool send ;
955
+
956
+ nfs4_stateid_copy (& stateid , & lo -> plh_stateid );
957
+ iomode = lo -> plh_return_iomode ;
958
+ send = pnfs_prepare_layoutreturn (lo );
959
+ spin_unlock (& inode -> i_lock );
960
+ if (send ) {
961
+ /* Send an async layoutreturn so we dont deadlock */
962
+ pnfs_send_layoutreturn (lo , & stateid , iomode , false);
963
+ }
964
+ } else
965
+ spin_unlock (& inode -> i_lock );
966
+ }
967
+
974
968
/*
975
969
* Initiates a LAYOUTRETURN(FILE), and removes the pnfs_layout_hdr
976
970
* when the layout segment list is empty.
@@ -1091,7 +1085,7 @@ bool pnfs_roc(struct inode *ino)
1091
1085
1092
1086
nfs4_stateid_copy (& stateid , & lo -> plh_stateid );
1093
1087
/* always send layoutreturn if being marked so */
1094
- if (test_and_clear_bit (NFS_LAYOUT_RETURN_BEFORE_CLOSE ,
1088
+ if (test_and_clear_bit (NFS_LAYOUT_RETURN_REQUESTED ,
1095
1089
& lo -> plh_flags ))
1096
1090
layoutreturn = pnfs_prepare_layoutreturn (lo );
1097
1091
@@ -1772,7 +1766,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
1772
1766
pnfs_set_plh_return_iomode (lo , return_range -> iomode );
1773
1767
if (!mark_lseg_invalid (lseg , tmp_list ))
1774
1768
remaining ++ ;
1775
- set_bit (NFS_LAYOUT_RETURN_BEFORE_CLOSE ,
1769
+ set_bit (NFS_LAYOUT_RETURN_REQUESTED ,
1776
1770
& lo -> plh_flags );
1777
1771
}
1778
1772
return remaining ;
0 commit comments