@ -149,6 +149,8 @@ nfs4_get_device_info(struct nfs_server *server,
*/
d = server - > pnfs_curr_ld - > alloc_deviceid_node ( server , pdev ,
gfp_flags ) ;
if ( d & & pdev - > nocache )
set_bit ( NFS_DEVICEID_NOCACHE , & d - > flags ) ;
out_free_pages :
for ( i = 0 ; i < max_pages ; i + + )
@ -235,6 +237,7 @@ nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
return ;
}
hlist_del_init_rcu ( & d - > node ) ;
clear_bit ( NFS_DEVICEID_NOCACHE , & d - > flags ) ;
spin_unlock ( & nfs4_deviceid_lock ) ;
/* balance the initial ref set in pnfs_insert_deviceid */
@ -269,6 +272,11 @@ EXPORT_SYMBOL_GPL(nfs4_init_deviceid_node);
bool
nfs4_put_deviceid_node ( struct nfs4_deviceid_node * d )
{
if ( test_bit ( NFS_DEVICEID_NOCACHE , & d - > flags ) ) {
if ( atomic_add_unless ( & d - > ref , - 1 , 2 ) )
return false ;
nfs4_delete_deviceid ( d - > ld , d - > nfs_client , & d - > deviceid ) ;
}
if ( ! atomic_dec_and_test ( & d - > ref ) )
return false ;
d - > ld - > free_deviceid_node ( d ) ;
@ -312,6 +320,7 @@ _deviceid_purge_client(const struct nfs_client *clp, long hash)
if ( d - > nfs_client = = clp & & atomic_read ( & d - > ref ) ) {
hlist_del_init_rcu ( & d - > node ) ;
hlist_add_head ( & d - > tmpnode , & tmp ) ;
clear_bit ( NFS_DEVICEID_NOCACHE , & d - > flags ) ;
}
rcu_read_unlock ( ) ;
spin_unlock ( & nfs4_deviceid_lock ) ;