diff options
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayout.h | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayoutdev.c | 28 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 9 |
4 files changed, 36 insertions, 9 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index a922e75af42e..0040a5ee6208 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -214,7 +214,9 @@ filelayout_read_pagelist(struct nfs_read_data *data) | |||
214 | idx = nfs4_fl_calc_ds_index(lseg, j); | 214 | idx = nfs4_fl_calc_ds_index(lseg, j); |
215 | ds = nfs4_fl_prepare_ds(lseg, idx); | 215 | ds = nfs4_fl_prepare_ds(lseg, idx); |
216 | if (!ds) { | 216 | if (!ds) { |
217 | printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__); | 217 | /* Either layout fh index faulty, or ds connect failed */ |
218 | set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags); | ||
219 | set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); | ||
218 | return PNFS_NOT_ATTEMPTED; | 220 | return PNFS_NOT_ATTEMPTED; |
219 | } | 221 | } |
220 | dprintk("%s USE DS:ip %x %hu\n", __func__, | 222 | dprintk("%s USE DS:ip %x %hu\n", __func__, |
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h index 23f1e1e2a0f5..ee0c907742b5 100644 --- a/fs/nfs/nfs4filelayout.h +++ b/fs/nfs/nfs4filelayout.h | |||
@@ -55,10 +55,14 @@ struct nfs4_pnfs_ds { | |||
55 | atomic_t ds_count; | 55 | atomic_t ds_count; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* nfs4_file_layout_dsaddr flags */ | ||
59 | #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 | ||
60 | |||
58 | struct nfs4_file_layout_dsaddr { | 61 | struct nfs4_file_layout_dsaddr { |
59 | struct hlist_node node; | 62 | struct hlist_node node; |
60 | struct nfs4_deviceid deviceid; | 63 | struct nfs4_deviceid deviceid; |
61 | atomic_t ref; | 64 | atomic_t ref; |
65 | unsigned long flags; | ||
62 | u32 stripe_count; | 66 | u32 stripe_count; |
63 | u8 *stripe_indices; | 67 | u8 *stripe_indices; |
64 | u32 ds_num; | 68 | u32 ds_num; |
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index f594ca35a996..68143c162e3b 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c | |||
@@ -606,6 +606,21 @@ nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j) | |||
606 | return flseg->fh_array[i]; | 606 | return flseg->fh_array[i]; |
607 | } | 607 | } |
608 | 608 | ||
609 | static void | ||
610 | filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, | ||
611 | int err, u32 ds_addr) | ||
612 | { | ||
613 | u32 *p = (u32 *)&dsaddr->deviceid; | ||
614 | |||
615 | printk(KERN_ERR "NFS: data server %x connection error %d." | ||
616 | " Deviceid [%x%x%x%x] marked out of use.\n", | ||
617 | ds_addr, err, p[0], p[1], p[2], p[3]); | ||
618 | |||
619 | spin_lock(&filelayout_deviceid_lock); | ||
620 | dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; | ||
621 | spin_unlock(&filelayout_deviceid_lock); | ||
622 | } | ||
623 | |||
609 | struct nfs4_pnfs_ds * | 624 | struct nfs4_pnfs_ds * |
610 | nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) | 625 | nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) |
611 | { | 626 | { |
@@ -619,13 +634,18 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) | |||
619 | } | 634 | } |
620 | 635 | ||
621 | if (!ds->ds_clp) { | 636 | if (!ds->ds_clp) { |
637 | struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); | ||
622 | int err; | 638 | int err; |
623 | 639 | ||
624 | err = nfs4_ds_connect(NFS_SERVER(lseg->pls_layout->plh_inode), | 640 | if (dsaddr->flags & NFS4_DEVICE_ID_NEG_ENTRY) { |
625 | dsaddr->ds_list[ds_idx]); | 641 | /* Already tried to connect, don't try again */ |
642 | dprintk("%s Deviceid marked out of use\n", __func__); | ||
643 | return NULL; | ||
644 | } | ||
645 | err = nfs4_ds_connect(s, ds); | ||
626 | if (err) { | 646 | if (err) { |
627 | printk(KERN_ERR "%s nfs4_ds_connect error %d\n", | 647 | filelayout_mark_devid_negative(dsaddr, err, |
628 | __func__, err); | 648 | ntohl(ds->ds_ip_addr)); |
629 | return NULL; | 649 | return NULL; |
630 | } | 650 | } |
631 | } | 651 | } |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 1f4c153441a1..3e545144a0b2 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -739,15 +739,16 @@ pnfs_update_layout(struct inode *ino, | |||
739 | dprintk("%s matches recall, use MDS\n", __func__); | 739 | dprintk("%s matches recall, use MDS\n", __func__); |
740 | goto out_unlock; | 740 | goto out_unlock; |
741 | } | 741 | } |
742 | /* Check to see if the layout for the given range already exists */ | ||
743 | lseg = pnfs_find_lseg(lo, iomode); | ||
744 | if (lseg) | ||
745 | goto out_unlock; | ||
746 | 742 | ||
747 | /* if LAYOUTGET already failed once we don't try again */ | 743 | /* if LAYOUTGET already failed once we don't try again */ |
748 | if (test_bit(lo_fail_bit(iomode), &nfsi->layout->plh_flags)) | 744 | if (test_bit(lo_fail_bit(iomode), &nfsi->layout->plh_flags)) |
749 | goto out_unlock; | 745 | goto out_unlock; |
750 | 746 | ||
747 | /* Check to see if the layout for the given range already exists */ | ||
748 | lseg = pnfs_find_lseg(lo, iomode); | ||
749 | if (lseg) | ||
750 | goto out_unlock; | ||
751 | |||
751 | if (pnfs_layoutgets_blocked(lo, NULL, 0)) | 752 | if (pnfs_layoutgets_blocked(lo, NULL, 0)) |
752 | goto out_unlock; | 753 | goto out_unlock; |
753 | atomic_inc(&lo->plh_outstanding); | 754 | atomic_inc(&lo->plh_outstanding); |