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>
This commit is contained in:
parent
183d9e7b11
commit
1b3c6d07e2
|
@ -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)
|
||||||
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)
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue