@@ -61,6 +61,7 @@ static void pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
61
61
u32 seq );
62
62
static bool pnfs_lseg_dec_and_remove_zero (struct pnfs_layout_segment * lseg ,
63
63
struct list_head * tmp_list );
64
+ static int pnfs_layout_return_on_reboot (struct pnfs_layout_hdr * lo );
64
65
65
66
/* Return the registered pnfs layout driver module matching given id */
66
67
static struct pnfs_layoutdriver_type *
@@ -937,25 +938,37 @@ int pnfs_layout_destroy_byfsid(struct nfs_client *clp, struct nfs_fsid *fsid,
937
938
return pnfs_layout_free_bulk_destroy_list (& layout_list , mode );
938
939
}
939
940
940
- int pnfs_layout_destroy_byclid (struct nfs_client * clp ,
941
- enum pnfs_layout_destroy_mode mode )
941
+ static void pnfs_layout_build_destroy_list_byclient (struct nfs_client * clp ,
942
+ struct list_head * list )
942
943
{
943
944
struct nfs_server * server ;
944
- LIST_HEAD (layout_list );
945
945
946
946
spin_lock (& clp -> cl_lock );
947
947
rcu_read_lock ();
948
948
restart :
949
949
list_for_each_entry_rcu (server , & clp -> cl_superblocks , client_link ) {
950
- if (pnfs_layout_bulk_destroy_byserver_locked (clp ,
951
- server ,
952
- & layout_list ) != 0 )
950
+ if (pnfs_layout_bulk_destroy_byserver_locked (clp , server ,
951
+ list ) != 0 )
953
952
goto restart ;
954
953
}
955
954
rcu_read_unlock ();
956
955
spin_unlock (& clp -> cl_lock );
956
+ }
957
957
958
- return pnfs_layout_free_bulk_destroy_list (& layout_list , mode );
958
+ static int pnfs_layout_do_destroy_byclid (struct nfs_client * clp ,
959
+ struct list_head * list ,
960
+ enum pnfs_layout_destroy_mode mode )
961
+ {
962
+ pnfs_layout_build_destroy_list_byclient (clp , list );
963
+ return pnfs_layout_free_bulk_destroy_list (list , mode );
964
+ }
965
+
966
+ int pnfs_layout_destroy_byclid (struct nfs_client * clp ,
967
+ enum pnfs_layout_destroy_mode mode )
968
+ {
969
+ LIST_HEAD (layout_list );
970
+
971
+ return pnfs_layout_do_destroy_byclid (clp , & layout_list , mode );
959
972
}
960
973
961
974
/*
@@ -971,6 +984,67 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
971
984
pnfs_layout_destroy_byclid (clp , PNFS_LAYOUT_INVALIDATE );
972
985
}
973
986
987
+ static void pnfs_layout_build_recover_list_byclient (struct nfs_client * clp ,
988
+ struct list_head * list )
989
+ {
990
+ struct nfs_server * server ;
991
+
992
+ spin_lock (& clp -> cl_lock );
993
+ rcu_read_lock ();
994
+ restart :
995
+ list_for_each_entry_rcu (server , & clp -> cl_superblocks , client_link ) {
996
+ if (!(server -> caps & NFS_CAP_REBOOT_LAYOUTRETURN ))
997
+ continue ;
998
+ if (pnfs_layout_bulk_destroy_byserver_locked (clp , server ,
999
+ list ) != 0 )
1000
+ goto restart ;
1001
+ }
1002
+ rcu_read_unlock ();
1003
+ spin_unlock (& clp -> cl_lock );
1004
+ }
1005
+
1006
+ static int pnfs_layout_bulk_list_reboot (struct list_head * list )
1007
+ {
1008
+ struct pnfs_layout_hdr * lo ;
1009
+ struct nfs_server * server ;
1010
+ int ret ;
1011
+
1012
+ list_for_each_entry (lo , list , plh_bulk_destroy ) {
1013
+ server = NFS_SERVER (lo -> plh_inode );
1014
+ ret = pnfs_layout_return_on_reboot (lo );
1015
+ switch (ret ) {
1016
+ case 0 :
1017
+ continue ;
1018
+ case - NFS4ERR_BAD_STATEID :
1019
+ server -> caps &= ~NFS_CAP_REBOOT_LAYOUTRETURN ;
1020
+ break ;
1021
+ case - NFS4ERR_NO_GRACE :
1022
+ break ;
1023
+ default :
1024
+ goto err ;
1025
+ }
1026
+ break ;
1027
+ }
1028
+ return 0 ;
1029
+ err :
1030
+ return ret ;
1031
+ }
1032
+
1033
+ int pnfs_layout_handle_reboot (struct nfs_client * clp )
1034
+ {
1035
+ LIST_HEAD (list );
1036
+ int ret = 0 , ret2 ;
1037
+
1038
+ pnfs_layout_build_recover_list_byclient (clp , & list );
1039
+ if (!list_empty (& list ))
1040
+ ret = pnfs_layout_bulk_list_reboot (& list );
1041
+ ret2 = pnfs_layout_do_destroy_byclid (clp , & list ,
1042
+ PNFS_LAYOUT_INVALIDATE );
1043
+ if (!ret )
1044
+ ret = ret2 ;
1045
+ return (ret == 0 ) ? 0 : - EAGAIN ;
1046
+ }
1047
+
974
1048
static void
975
1049
pnfs_set_layout_cred (struct pnfs_layout_hdr * lo , const struct cred * cred )
976
1050
{
@@ -1445,6 +1519,24 @@ pnfs_commit_and_return_layout(struct inode *inode)
1445
1519
return ret ;
1446
1520
}
1447
1521
1522
+ static int pnfs_layout_return_on_reboot (struct pnfs_layout_hdr * lo )
1523
+ {
1524
+ struct inode * inode = lo -> plh_inode ;
1525
+ const struct cred * cred ;
1526
+
1527
+ spin_lock (& inode -> i_lock );
1528
+ if (!pnfs_layout_is_valid (lo )) {
1529
+ spin_unlock (& inode -> i_lock );
1530
+ return 0 ;
1531
+ }
1532
+ cred = get_cred (lo -> plh_lc_cred );
1533
+ pnfs_get_layout_hdr (lo );
1534
+ spin_unlock (& inode -> i_lock );
1535
+
1536
+ return pnfs_send_layoutreturn (lo , & zero_stateid , & cred , IOMODE_ANY ,
1537
+ PNFS_FL_LAYOUTRETURN_PRIVILEGED );
1538
+ }
1539
+
1448
1540
bool pnfs_roc (struct inode * ino ,
1449
1541
struct nfs4_layoutreturn_args * args ,
1450
1542
struct nfs4_layoutreturn_res * res ,
0 commit comments