3636
3737#define NFSDBG_FACILITY NFSDBG_PNFS_LD
3838
39- /*
40- * Device ID RCU cache. A device ID is unique per client ID and layout type.
41- */
42- #define NFS4_FL_DEVICE_ID_HASH_BITS 5
43- #define NFS4_FL_DEVICE_ID_HASH_SIZE (1 << NFS4_FL_DEVICE_ID_HASH_BITS)
44- #define NFS4_FL_DEVICE_ID_HASH_MASK (NFS4_FL_DEVICE_ID_HASH_SIZE - 1)
45-
46- static inline u32
47- nfs4_fl_deviceid_hash (struct nfs4_deviceid * id )
48- {
49- unsigned char * cptr = (unsigned char * )id -> data ;
50- unsigned int nbytes = NFS4_DEVICEID4_SIZE ;
51- u32 x = 0 ;
52-
53- while (nbytes -- ) {
54- x *= 37 ;
55- x += * cptr ++ ;
56- }
57- return x & NFS4_FL_DEVICE_ID_HASH_MASK ;
58- }
59-
60- static struct hlist_head filelayout_deviceid_cache [NFS4_FL_DEVICE_ID_HASH_SIZE ];
61- static DEFINE_SPINLOCK (filelayout_deviceid_lock );
62-
6339/*
6440 * Data server cache
6541 *
@@ -89,27 +65,6 @@ print_ds(struct nfs4_pnfs_ds *ds)
8965 ds -> ds_clp ? ds -> ds_clp -> cl_exchange_flags : 0 );
9066}
9167
92- void
93- print_ds_list (struct nfs4_file_layout_dsaddr * dsaddr )
94- {
95- int i ;
96-
97- ifdebug (FACILITY ) {
98- printk ("%s dsaddr->ds_num %d\n" , __func__ ,
99- dsaddr -> ds_num );
100- for (i = 0 ; i < dsaddr -> ds_num ; i ++ )
101- print_ds (dsaddr -> ds_list [i ]);
102- }
103- }
104-
105- void print_deviceid (struct nfs4_deviceid * id )
106- {
107- u32 * p = (u32 * )id ;
108-
109- dprintk ("%s: device id= [%x%x%x%x]\n" , __func__ ,
110- p [0 ], p [1 ], p [2 ], p [3 ]);
111- }
112-
11368/* nfs4_ds_cache_lock is held */
11469static struct nfs4_pnfs_ds *
11570_data_server_lookup_locked (u32 ip_addr , u32 port )
@@ -207,7 +162,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
207162 struct nfs4_pnfs_ds * ds ;
208163 int i ;
209164
210- print_deviceid (& dsaddr -> deviceid );
165+ nfs4_print_deviceid (& dsaddr -> id_node . deviceid );
211166
212167 for (i = 0 ; i < dsaddr -> ds_num ; i ++ ) {
213168 ds = dsaddr -> ds_list [i ];
@@ -431,8 +386,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
431386 dsaddr -> stripe_indices = stripe_indices ;
432387 stripe_indices = NULL ;
433388 dsaddr -> ds_num = num ;
434- dsaddr -> nfs_client = NFS_SERVER (ino )-> nfs_client ;
435- memcpy ( & dsaddr -> deviceid , & pdev -> dev_id , sizeof ( pdev -> dev_id ) );
389+ nfs4_init_deviceid_node ( & dsaddr -> id_node , NFS_SERVER (ino )-> nfs_client ,
390+ & pdev -> dev_id );
436391
437392 for (i = 0 ; i < dsaddr -> ds_num ; i ++ ) {
438393 int j ;
@@ -505,8 +460,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
505460static struct nfs4_file_layout_dsaddr *
506461decode_and_add_device (struct inode * inode , struct pnfs_device * dev , gfp_t gfp_flags )
507462{
508- struct nfs4_file_layout_dsaddr * d , * new ;
509- long hash ;
463+ struct nfs4_deviceid_node * d ;
464+ struct nfs4_file_layout_dsaddr * n , * new ;
510465
511466 new = decode_device (inode , dev , gfp_flags );
512467 if (!new ) {
@@ -515,20 +470,13 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
515470 return NULL ;
516471 }
517472
518- spin_lock (& filelayout_deviceid_lock );
519- d = nfs4_fl_find_get_deviceid (new -> nfs_client , & new -> deviceid );
520- if (d ) {
521- spin_unlock (& filelayout_deviceid_lock );
473+ d = nfs4_insert_deviceid_node (& new -> id_node );
474+ n = container_of (d , struct nfs4_file_layout_dsaddr , id_node );
475+ if (n != new ) {
522476 nfs4_fl_free_deviceid (new );
523- return d ;
477+ return n ;
524478 }
525479
526- INIT_HLIST_NODE (& new -> node );
527- atomic_set (& new -> ref , 1 );
528- hash = nfs4_fl_deviceid_hash (& new -> deviceid );
529- hlist_add_head_rcu (& new -> node , & filelayout_deviceid_cache [hash ]);
530- spin_unlock (& filelayout_deviceid_lock );
531-
532480 return new ;
533481}
534482
@@ -600,34 +548,8 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla
600548void
601549nfs4_fl_put_deviceid (struct nfs4_file_layout_dsaddr * dsaddr )
602550{
603- if (atomic_dec_and_lock (& dsaddr -> ref , & filelayout_deviceid_lock )) {
604- hlist_del_rcu (& dsaddr -> node );
605- spin_unlock (& filelayout_deviceid_lock );
606-
607- synchronize_rcu ();
551+ if (nfs4_put_deviceid_node (& dsaddr -> id_node ))
608552 nfs4_fl_free_deviceid (dsaddr );
609- }
610- }
611-
612- struct nfs4_file_layout_dsaddr *
613- nfs4_fl_find_get_deviceid (struct nfs_client * clp , struct nfs4_deviceid * id )
614- {
615- struct nfs4_file_layout_dsaddr * d ;
616- struct hlist_node * n ;
617- long hash = nfs4_fl_deviceid_hash (id );
618-
619- rcu_read_lock ();
620- hlist_for_each_entry_rcu (d , n , & filelayout_deviceid_cache [hash ], node ) {
621- if (d -> nfs_client == clp && !memcmp (& d -> deviceid , id , sizeof (* id ))) {
622- if (!atomic_inc_not_zero (& d -> ref ))
623- goto fail ;
624- rcu_read_unlock ();
625- return d ;
626- }
627- }
628- fail :
629- rcu_read_unlock ();
630- return NULL ;
631553}
632554
633555/*
@@ -675,15 +597,15 @@ static void
675597filelayout_mark_devid_negative (struct nfs4_file_layout_dsaddr * dsaddr ,
676598 int err , u32 ds_addr )
677599{
678- u32 * p = (u32 * )& dsaddr -> deviceid ;
600+ u32 * p = (u32 * )& dsaddr -> id_node . deviceid ;
679601
680602 printk (KERN_ERR "NFS: data server %x connection error %d."
681603 " Deviceid [%x%x%x%x] marked out of use.\n" ,
682604 ds_addr , err , p [0 ], p [1 ], p [2 ], p [3 ]);
683605
684- spin_lock (& filelayout_deviceid_lock );
606+ spin_lock (& nfs4_ds_cache_lock );
685607 dsaddr -> flags |= NFS4_DEVICE_ID_NEG_ENTRY ;
686- spin_unlock (& filelayout_deviceid_lock );
608+ spin_unlock (& nfs4_ds_cache_lock );
687609}
688610
689611struct nfs4_pnfs_ds *
0 commit comments