16
16
#include "nfs4session.h"
17
17
#include "internal.h"
18
18
#include "pnfs.h"
19
+ #include "netns.h"
19
20
20
21
#define NFSDBG_FACILITY NFSDBG_PNFS
21
22
@@ -504,14 +505,14 @@ EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist);
504
505
/*
505
506
* Data server cache
506
507
*
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:
509
512
* - set to 1 on allocation
510
513
* - incremented when a device id maps a data server already in the cache.
511
514
* - decremented when deviceid is removed from the cache.
512
515
*/
513
- static DEFINE_SPINLOCK (nfs4_ds_cache_lock );
514
- static LIST_HEAD (nfs4_data_server_cache );
515
516
516
517
/* Debug routines */
517
518
static void
@@ -604,12 +605,12 @@ _same_data_server_addrs_locked(const struct list_head *dsaddrs1,
604
605
* Lookup DS by addresses. nfs4_ds_cache_lock is held
605
606
*/
606
607
static 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 )
608
609
{
609
610
struct nfs4_pnfs_ds * ds ;
610
611
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 ))
613
614
return ds ;
614
615
return NULL ;
615
616
}
@@ -653,10 +654,11 @@ static void destroy_ds(struct nfs4_pnfs_ds *ds)
653
654
654
655
void nfs4_pnfs_ds_put (struct nfs4_pnfs_ds * ds )
655
656
{
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 )) {
658
660
list_del_init (& ds -> ds_node );
659
- spin_unlock (& nfs4_ds_cache_lock );
661
+ spin_unlock (& nn -> nfs4_data_server_lock );
660
662
destroy_ds (ds );
661
663
}
662
664
}
@@ -718,6 +720,7 @@ nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags)
718
720
struct nfs4_pnfs_ds *
719
721
nfs4_pnfs_ds_add (const struct net * net , struct list_head * dsaddrs , gfp_t gfp_flags )
720
722
{
723
+ struct nfs_net * nn = net_generic (net , nfs_net_id );
721
724
struct nfs4_pnfs_ds * tmp_ds , * ds = NULL ;
722
725
char * remotestr ;
723
726
@@ -733,8 +736,8 @@ nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_fla
733
736
/* this is only used for debugging, so it's ok if its NULL */
734
737
remotestr = nfs4_pnfs_remotestr (dsaddrs , gfp_flags );
735
738
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 );
738
741
if (tmp_ds == NULL ) {
739
742
INIT_LIST_HEAD (& ds -> ds_addrs );
740
743
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
743
746
INIT_LIST_HEAD (& ds -> ds_node );
744
747
ds -> ds_net = net ;
745
748
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 );
747
750
dprintk ("%s add new data server %s\n" , __func__ ,
748
751
ds -> ds_remotestr );
749
752
} else {
@@ -755,7 +758,7 @@ nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_fla
755
758
refcount_read (& tmp_ds -> ds_count ));
756
759
ds = tmp_ds ;
757
760
}
758
- spin_unlock (& nfs4_ds_cache_lock );
761
+ spin_unlock (& nn -> nfs4_data_server_lock );
759
762
out :
760
763
return ds ;
761
764
}
0 commit comments