aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@poochiereds.net>2016-05-17 12:28:48 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-05-17 15:48:13 -0400
commit1b3c6d07e29515064aca8a9f86efaea7da4da027 (patch)
tree9bff3d864babadc95af859903a2b16fd888c0f36
parent183d9e7b112aaed0d19c16ffcf0f8c3a86dc71e0 (diff)
pnfs: make pnfs_layout_process more robust
It can return NULL if layoutgets are blocked currently. Fix it to return -EAGAIN in that case, so we can properly handle it in pnfs_update_layout. Also, clean up and simplify the error handling -- eliminate "status" and just use "lseg". Signed-off-by: Jeff Layton <jeff.layton@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/pnfs.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 46339a7fb191..79ae3049608d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1708,21 +1708,19 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
1708 struct pnfs_layout_segment *lseg; 1708 struct pnfs_layout_segment *lseg;
1709 struct inode *ino = lo->plh_inode; 1709 struct inode *ino = lo->plh_inode;
1710 LIST_HEAD(free_me); 1710 LIST_HEAD(free_me);
1711 int status = -EINVAL;
1712 1711
1713 if (!pnfs_sanity_check_layout_range(&res->range)) 1712 if (!pnfs_sanity_check_layout_range(&res->range))
1714 goto out; 1713 return ERR_PTR(-EINVAL);
1715 1714
1716 /* Inject layout blob into I/O device driver */ 1715 /* Inject layout blob into I/O device driver */
1717 lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); 1716 lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags);
1718 if (!lseg || IS_ERR(lseg)) { 1717 if (IS_ERR_OR_NULL(lseg)) {
1719 if (!lseg) 1718 if (!lseg)
1720 status = -ENOMEM; 1719 lseg = ERR_PTR(-ENOMEM);
1721 else 1720
1722 status = PTR_ERR(lseg); 1721 dprintk("%s: Could not allocate layout: error %ld\n",
1723 dprintk("%s: Could not allocate layout: error %d\n", 1722 __func__, PTR_ERR(lseg));
1724 __func__, status); 1723 return lseg;
1725 goto out;
1726 } 1724 }
1727 1725
1728 init_lseg(lo, lseg); 1726 init_lseg(lo, lseg);
@@ -1732,15 +1730,14 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
1732 spin_lock(&ino->i_lock); 1730 spin_lock(&ino->i_lock);
1733 if (pnfs_layoutgets_blocked(lo)) { 1731 if (pnfs_layoutgets_blocked(lo)) {
1734 dprintk("%s forget reply due to state\n", __func__); 1732 dprintk("%s forget reply due to state\n", __func__);
1735 goto out_forget_reply; 1733 goto out_forget;
1736 } 1734 }
1737 1735
1738 if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { 1736 if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
1739 /* existing state ID, make sure the sequence number matches. */ 1737 /* existing state ID, make sure the sequence number matches. */
1740 if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { 1738 if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
1741 dprintk("%s forget reply due to sequence\n", __func__); 1739 dprintk("%s forget reply due to sequence\n", __func__);
1742 status = -EAGAIN; 1740 goto out_forget;
1743 goto out_forget_reply;
1744 } 1741 }
1745 pnfs_set_layout_stateid(lo, &res->stateid, false); 1742 pnfs_set_layout_stateid(lo, &res->stateid, false);
1746 } else { 1743 } else {
@@ -1766,14 +1763,12 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
1766 spin_unlock(&ino->i_lock); 1763 spin_unlock(&ino->i_lock);
1767 pnfs_free_lseg_list(&free_me); 1764 pnfs_free_lseg_list(&free_me);
1768 return lseg; 1765 return lseg;
1769out:
1770 return ERR_PTR(status);
1771 1766
1772out_forget_reply: 1767out_forget:
1773 spin_unlock(&ino->i_lock); 1768 spin_unlock(&ino->i_lock);
1774 lseg->pls_layout = lo; 1769 lseg->pls_layout = lo;
1775 NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg); 1770 NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg);
1776 goto out; 1771 return ERR_PTR(-EAGAIN);
1777} 1772}
1778 1773
1779static void 1774static void