1616#include "nfs4session.h"
1717#include "internal.h"
1818#include "pnfs.h"
19+ #include "netns.h"
1920
2021#define NFSDBG_FACILITY NFSDBG_PNFS
2122
@@ -504,14 +505,14 @@ EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist);
504505/*
505506 * Data server cache
506507 *
507- * Data servers can be mapped to different device ids.
508- * nfs4_pnfs_ds reference counting
508+ * Data servers can be mapped to different device ids, but should
509+ * never be shared between net namespaces.
510+ *
511+ * nfs4_pnfs_ds reference counting:
509512 * - set to 1 on allocation
510513 * - incremented when a device id maps a data server already in the cache.
511514 * - decremented when deviceid is removed from the cache.
512515 */
513- static DEFINE_SPINLOCK (nfs4_ds_cache_lock );
514- static LIST_HEAD (nfs4_data_server_cache );
515516
516517/* Debug routines */
517518static void
@@ -604,12 +605,12 @@ _same_data_server_addrs_locked(const struct list_head *dsaddrs1,
604605 * Lookup DS by addresses. nfs4_ds_cache_lock is held
605606 */
606607static struct nfs4_pnfs_ds *
607- _data_server_lookup_locked (const struct net * net , const struct list_head * dsaddrs )
608+ _data_server_lookup_locked (const struct nfs_net * nn , const struct list_head * dsaddrs )
608609{
609610 struct nfs4_pnfs_ds * ds ;
610611
611- list_for_each_entry (ds , & nfs4_data_server_cache , ds_node )
612- if (ds -> ds_net == net && _same_data_server_addrs_locked (& ds -> ds_addrs , dsaddrs ))
612+ list_for_each_entry (ds , & nn -> nfs4_data_server_cache , ds_node )
613+ if (_same_data_server_addrs_locked (& ds -> ds_addrs , dsaddrs ))
613614 return ds ;
614615 return NULL ;
615616}
@@ -653,10 +654,11 @@ static void destroy_ds(struct nfs4_pnfs_ds *ds)
653654
654655void nfs4_pnfs_ds_put (struct nfs4_pnfs_ds * ds )
655656{
656- if (refcount_dec_and_lock (& ds -> ds_count ,
657- & nfs4_ds_cache_lock )) {
657+ struct nfs_net * nn = net_generic (ds -> ds_net , nfs_net_id );
658+
659+ if (refcount_dec_and_lock (& ds -> ds_count , & nn -> nfs4_data_server_lock )) {
658660 list_del_init (& ds -> ds_node );
659- spin_unlock (& nfs4_ds_cache_lock );
661+ spin_unlock (& nn -> nfs4_data_server_lock );
660662 destroy_ds (ds );
661663 }
662664}
@@ -718,6 +720,7 @@ nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags)
718720struct nfs4_pnfs_ds *
719721nfs4_pnfs_ds_add (const struct net * net , struct list_head * dsaddrs , gfp_t gfp_flags )
720722{
723+ struct nfs_net * nn = net_generic (net , nfs_net_id );
721724 struct nfs4_pnfs_ds * tmp_ds , * ds = NULL ;
722725 char * remotestr ;
723726
@@ -733,8 +736,8 @@ nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_fla
733736 /* this is only used for debugging, so it's ok if its NULL */
734737 remotestr = nfs4_pnfs_remotestr (dsaddrs , gfp_flags );
735738
736- spin_lock (& nfs4_ds_cache_lock );
737- tmp_ds = _data_server_lookup_locked (net , dsaddrs );
739+ spin_lock (& nn -> nfs4_data_server_lock );
740+ tmp_ds = _data_server_lookup_locked (nn , dsaddrs );
738741 if (tmp_ds == NULL ) {
739742 INIT_LIST_HEAD (& ds -> ds_addrs );
740743 list_splice_init (dsaddrs , & ds -> ds_addrs );
@@ -743,7 +746,7 @@ nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_fla
743746 INIT_LIST_HEAD (& ds -> ds_node );
744747 ds -> ds_net = net ;
745748 ds -> ds_clp = NULL ;
746- list_add (& ds -> ds_node , & nfs4_data_server_cache );
749+ list_add (& ds -> ds_node , & nn -> nfs4_data_server_cache );
747750 dprintk ("%s add new data server %s\n" , __func__ ,
748751 ds -> ds_remotestr );
749752 } else {
@@ -755,7 +758,7 @@ nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_fla
755758 refcount_read (& tmp_ds -> ds_count ));
756759 ds = tmp_ds ;
757760 }
758- spin_unlock (& nfs4_ds_cache_lock );
761+ spin_unlock (& nn -> nfs4_data_server_lock );
759762out :
760763 return ds ;
761764}
0 commit comments