aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayoutdev.c
diff options
context:
space:
mode:
authorBenny Halevy <bhalevy@panasas.com>2011-05-19 22:14:47 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-05-29 05:09:48 -0400
commita1eaecbc4c8307e27772d6584ef85a2e93250661 (patch)
tree940549d45db98a5bcfe22501de0bbe9c96de4c8e /fs/nfs/nfs4filelayoutdev.c
parent45df3c8b0f3a58facb125d7631890426706c0bfa (diff)
NFSv4.1: make deviceid cache global
Move deviceid cache from the pnfs files layout driver to the generic layer in preparation for the objects layout driver. Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Diffstat (limited to 'fs/nfs/nfs4filelayoutdev.c')
-rw-r--r--fs/nfs/nfs4filelayoutdev.c104
1 files changed, 13 insertions, 91 deletions
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 42e326637271..eda4527a57eb 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -37,30 +37,6 @@
37#define NFSDBG_FACILITY NFSDBG_PNFS_LD 37#define NFSDBG_FACILITY NFSDBG_PNFS_LD
38 38
39/* 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
46static inline u32
47nfs4_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
60static struct hlist_head filelayout_deviceid_cache[NFS4_FL_DEVICE_ID_HASH_SIZE];
61static DEFINE_SPINLOCK(filelayout_deviceid_lock);
62
63/*
64 * Data server cache 40 * Data server cache
65 * 41 *
66 * Data servers can be mapped to different device ids. 42 * Data servers can be mapped to different device ids.
@@ -89,27 +65,6 @@ print_ds(struct nfs4_pnfs_ds *ds)
89 ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0); 65 ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0);
90} 66}
91 67
92void
93print_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
105void 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
113/* nfs4_ds_cache_lock is held */ 68/* nfs4_ds_cache_lock is held */
114static struct nfs4_pnfs_ds * 69static struct nfs4_pnfs_ds *
115_data_server_lookup_locked(u32 ip_addr, u32 port) 70_data_server_lookup_locked(u32 ip_addr, u32 port)
@@ -207,7 +162,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
207 struct nfs4_pnfs_ds *ds; 162 struct nfs4_pnfs_ds *ds;
208 int i; 163 int i;
209 164
210 print_deviceid(&dsaddr->deviceid); 165 nfs4_print_deviceid(&dsaddr->id_node.deviceid);
211 166
212 for (i = 0; i < dsaddr->ds_num; i++) { 167 for (i = 0; i < dsaddr->ds_num; i++) {
213 ds = dsaddr->ds_list[i]; 168 ds = dsaddr->ds_list[i];
@@ -431,8 +386,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
431 dsaddr->stripe_indices = stripe_indices; 386 dsaddr->stripe_indices = stripe_indices;
432 stripe_indices = NULL; 387 stripe_indices = NULL;
433 dsaddr->ds_num = num; 388 dsaddr->ds_num = num;
434 dsaddr->nfs_client = NFS_SERVER(ino)->nfs_client; 389 nfs4_init_deviceid_node(&dsaddr->id_node, NFS_SERVER(ino)->nfs_client,
435 memcpy(&dsaddr->deviceid, &pdev->dev_id, sizeof(pdev->dev_id)); 390 &pdev->dev_id);
436 391
437 for (i = 0; i < dsaddr->ds_num; i++) { 392 for (i = 0; i < dsaddr->ds_num; i++) {
438 int j; 393 int j;
@@ -505,8 +460,8 @@ out_err:
505static struct nfs4_file_layout_dsaddr * 460static struct nfs4_file_layout_dsaddr *
506decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) 461decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags)
507{ 462{
508 struct nfs4_file_layout_dsaddr *d, *new; 463 struct nfs4_deviceid_node *d;
509 long hash; 464 struct nfs4_file_layout_dsaddr *n, *new;
510 465
511 new = decode_device(inode, dev, gfp_flags); 466 new = decode_device(inode, dev, gfp_flags);
512 if (!new) { 467 if (!new) {
@@ -515,20 +470,13 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
515 return NULL; 470 return NULL;
516 } 471 }
517 472
518 spin_lock(&filelayout_deviceid_lock); 473 d = nfs4_insert_deviceid_node(&new->id_node);
519 d = nfs4_fl_find_get_deviceid(new->nfs_client, &new->deviceid); 474 n = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
520 if (d) { 475 if (n != new) {
521 spin_unlock(&filelayout_deviceid_lock);
522 nfs4_fl_free_deviceid(new); 476 nfs4_fl_free_deviceid(new);
523 return d; 477 return n;
524 } 478 }
525 479
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
532 return new; 480 return new;
533} 481}
534 482
@@ -600,34 +548,8 @@ out_free:
600void 548void
601nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) 549nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
602{ 550{
603 if (atomic_dec_and_lock(&dsaddr->ref, &filelayout_deviceid_lock)) { 551 if (nfs4_put_deviceid_node(&dsaddr->id_node))
604 hlist_del_rcu(&dsaddr->node);
605 spin_unlock(&filelayout_deviceid_lock);
606
607 synchronize_rcu();
608 nfs4_fl_free_deviceid(dsaddr); 552 nfs4_fl_free_deviceid(dsaddr);
609 }
610}
611
612struct nfs4_file_layout_dsaddr *
613nfs4_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 }
628fail:
629 rcu_read_unlock();
630 return NULL;
631} 553}
632 554
633/* 555/*
@@ -675,15 +597,15 @@ static void
675filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, 597filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr,
676 int err, u32 ds_addr) 598 int err, u32 ds_addr)
677{ 599{
678 u32 *p = (u32 *)&dsaddr->deviceid; 600 u32 *p = (u32 *)&dsaddr->id_node.deviceid;
679 601
680 printk(KERN_ERR "NFS: data server %x connection error %d." 602 printk(KERN_ERR "NFS: data server %x connection error %d."
681 " Deviceid [%x%x%x%x] marked out of use.\n", 603 " Deviceid [%x%x%x%x] marked out of use.\n",
682 ds_addr, err, p[0], p[1], p[2], p[3]); 604 ds_addr, err, p[0], p[1], p[2], p[3]);
683 605
684 spin_lock(&filelayout_deviceid_lock); 606 spin_lock(&nfs4_ds_cache_lock);
685 dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; 607 dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY;
686 spin_unlock(&filelayout_deviceid_lock); 608 spin_unlock(&nfs4_ds_cache_lock);
687} 609}
688 610
689struct nfs4_pnfs_ds * 611struct nfs4_pnfs_ds *