Commit 1b3c6d07 authored by Jeff Layton's avatar Jeff Layton Committed by Anna Schumaker

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: default avatarJeff Layton <jeff.layton@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 183d9e7b
...@@ -1708,21 +1708,19 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1708,21 +1708,19 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
struct pnfs_layout_segment *lseg; struct pnfs_layout_segment *lseg;
struct inode *ino = lo->plh_inode; struct inode *ino = lo->plh_inode;
LIST_HEAD(free_me); LIST_HEAD(free_me);
int status = -EINVAL;
if (!pnfs_sanity_check_layout_range(&res->range)) if (!pnfs_sanity_check_layout_range(&res->range))
goto out; return ERR_PTR(-EINVAL);
/* Inject layout blob into I/O device driver */ /* Inject layout blob into I/O device driver */
lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags);
if (!lseg || IS_ERR(lseg)) { if (IS_ERR_OR_NULL(lseg)) {
if (!lseg) if (!lseg)
status = -ENOMEM; lseg = ERR_PTR(-ENOMEM);
else
status = PTR_ERR(lseg); dprintk("%s: Could not allocate layout: error %ld\n",
dprintk("%s: Could not allocate layout: error %d\n", __func__, PTR_ERR(lseg));
__func__, status); return lseg;
goto out;
} }
init_lseg(lo, lseg); init_lseg(lo, lseg);
...@@ -1732,15 +1730,14 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1732,15 +1730,14 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
spin_lock(&ino->i_lock); spin_lock(&ino->i_lock);
if (pnfs_layoutgets_blocked(lo)) { if (pnfs_layoutgets_blocked(lo)) {
dprintk("%s forget reply due to state\n", __func__); dprintk("%s forget reply due to state\n", __func__);
goto out_forget_reply; goto out_forget;
} }
if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) {
/* existing state ID, make sure the sequence number matches. */ /* existing state ID, make sure the sequence number matches. */
if (pnfs_layout_stateid_blocked(lo, &res->stateid)) { if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
dprintk("%s forget reply due to sequence\n", __func__); dprintk("%s forget reply due to sequence\n", __func__);
status = -EAGAIN; goto out_forget;
goto out_forget_reply;
} }
pnfs_set_layout_stateid(lo, &res->stateid, false); pnfs_set_layout_stateid(lo, &res->stateid, false);
} else { } else {
...@@ -1766,14 +1763,12 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) ...@@ -1766,14 +1763,12 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
spin_unlock(&ino->i_lock); spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&free_me); pnfs_free_lseg_list(&free_me);
return lseg; return lseg;
out:
return ERR_PTR(status);
out_forget_reply: out_forget:
spin_unlock(&ino->i_lock); spin_unlock(&ino->i_lock);
lseg->pls_layout = lo; lseg->pls_layout = lo;
NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg); NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg);
goto out; return ERR_PTR(-EAGAIN);
} }
static void static void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment