Skip to content

Commit

Permalink
pNFS: Fix post-layoutget error handling in pnfs_update_layout()
Browse files Browse the repository at this point in the history
The non-retry error path is currently broken and ends up releasing the
reference to the layout twice. It also can end up clearing the
NFS_LAYOUT_FIRST_LAYOUTGET flag twice, causing a race.

In addition, the retry path will fail to decrement the plh_outstanding
counter.

Fixes: 183d9e7 ("pnfs: rework LAYOUTGET retry handling")
Cc: stable@vger.kernel.org # 4.7
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
  • Loading branch information
Trond Myklebust committed Jul 19, 2016
1 parent 8487c47 commit 56b38a1
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1645,33 +1645,34 @@ pnfs_update_layout(struct inode *ino,
lseg = send_layoutget(lo, ctx, &stateid, &arg, &timeout, gfp_flags);
trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
atomic_dec(&lo->plh_outstanding);
if (IS_ERR(lseg)) {
switch(PTR_ERR(lseg)) {
case -ERECALLCONFLICT:
if (time_after(jiffies, giveup))
lseg = NULL;
/* Fallthrough */
case -EAGAIN:
pnfs_put_layout_hdr(lo);
if (first)
pnfs_clear_first_layoutget(lo);
if (lseg) {
trace_pnfs_update_layout(ino, pos, count,
iomode, lo, lseg, PNFS_UPDATE_LAYOUT_RETRY);
goto lookup_again;
}
/* Fallthrough */
break;
default:
if (!nfs_error_is_fatal(PTR_ERR(lseg))) {
pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
lseg = NULL;
}
goto out_put_layout_hdr;
}
if (lseg) {
if (first)
pnfs_clear_first_layoutget(lo);
trace_pnfs_update_layout(ino, pos, count,
iomode, lo, lseg, PNFS_UPDATE_LAYOUT_RETRY);
pnfs_put_layout_hdr(lo);
goto lookup_again;
}
} else {
pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
}

atomic_dec(&lo->plh_outstanding);
out_put_layout_hdr:
if (first)
pnfs_clear_first_layoutget(lo);
Expand Down

0 comments on commit 56b38a1

Please sign in to comment.