@@ -61,6 +61,7 @@ static void pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
6161 u32 seq );
6262static bool pnfs_lseg_dec_and_remove_zero (struct pnfs_layout_segment * lseg ,
6363 struct list_head * tmp_list );
64+ static int pnfs_layout_return_on_reboot (struct pnfs_layout_hdr * lo );
6465
6566/* Return the registered pnfs layout driver module matching given id */
6667static struct pnfs_layoutdriver_type *
@@ -937,25 +938,37 @@ int pnfs_layout_destroy_byfsid(struct nfs_client *clp, struct nfs_fsid *fsid,
937938 return pnfs_layout_free_bulk_destroy_list (& layout_list , mode );
938939}
939940
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 )
942943{
943944 struct nfs_server * server ;
944- LIST_HEAD (layout_list );
945945
946946 spin_lock (& clp -> cl_lock );
947947 rcu_read_lock ();
948948restart :
949949 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 )
953952 goto restart ;
954953 }
955954 rcu_read_unlock ();
956955 spin_unlock (& clp -> cl_lock );
956+ }
957957
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 );
959972}
960973
961974/*
@@ -971,6 +984,67 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
971984 pnfs_layout_destroy_byclid (clp , PNFS_LAYOUT_INVALIDATE );
972985}
973986
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+
9741048static void
9751049pnfs_set_layout_cred (struct pnfs_layout_hdr * lo , const struct cred * cred )
9761050{
@@ -1445,6 +1519,24 @@ pnfs_commit_and_return_layout(struct inode *inode)
14451519 return ret ;
14461520}
14471521
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+
14481540bool pnfs_roc (struct inode * ino ,
14491541 struct nfs4_layoutreturn_args * args ,
14501542 struct nfs4_layoutreturn_res * res ,
0 commit comments