Skip to content

Commit

Permalink
NFS41: pop some layoutget errors to application
Browse files Browse the repository at this point in the history
For ERESTARTSYS/EIO/EROFS/ENOSPC/E2BIG in layoutget, we
should just bail out instead of hiding the error and
retrying inband IO.

Change all the call sites to pop the error all the way up.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
  • Loading branch information
Peng Tao authored and Trond Myklebust committed Dec 28, 2015
1 parent d0379a5 commit d600ad1
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 14 deletions.
15 changes: 14 additions & 1 deletion fs/nfs/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,20 +670,28 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)

req = nfs_list_entry(reqs.next);
nfs_direct_setup_mirroring(dreq, &desc, req);
if (desc.pg_error < 0) {
list_splice_init(&reqs, &failed);
goto out_failed;
}

list_for_each_entry_safe(req, tmp, &reqs, wb_list) {
if (!nfs_pageio_add_request(&desc, req)) {
nfs_list_remove_request(req);
nfs_list_add_request(req, &failed);
spin_lock(cinfo.lock);
dreq->flags = 0;
dreq->error = -EIO;
if (desc.pg_error < 0)
dreq->error = desc.pg_error;
else
dreq->error = -EIO;
spin_unlock(cinfo.lock);
}
nfs_release_request(req);
}
nfs_pageio_complete(&desc);

out_failed:
while (!list_empty(&failed)) {
req = nfs_list_entry(failed.next);
nfs_list_remove_request(req);
Expand Down Expand Up @@ -900,6 +908,11 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
}

nfs_direct_setup_mirroring(dreq, &desc, req);
if (desc.pg_error < 0) {
nfs_free_request(req);
result = desc.pg_error;
break;
}

nfs_lock_request(req);
req->wb_index = pos >> PAGE_SHIFT;
Expand Down
17 changes: 15 additions & 2 deletions fs/nfs/filelayout/filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,13 +883,19 @@ static void
filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req)
{
if (!pgio->pg_lseg)
if (!pgio->pg_lseg) {
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
0,
NFS4_MAX_UINT64,
IOMODE_READ,
GFP_KERNEL);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
return;
}
}
/* If no lseg, fall back to read through mds */
if (pgio->pg_lseg == NULL)
nfs_pageio_reset_read_mds(pgio);
Expand All @@ -902,13 +908,20 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
struct nfs_commit_info cinfo;
int status;

if (!pgio->pg_lseg)
if (!pgio->pg_lseg) {
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
0,
NFS4_MAX_UINT64,
IOMODE_RW,
GFP_NOFS);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
return;
}
}

/* If no lseg, fall back to write through mds */
if (pgio->pg_lseg == NULL)
goto out_mds;
Expand Down
25 changes: 22 additions & 3 deletions fs/nfs/flexfilelayout/flexfilelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,13 +795,19 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
int ds_idx;

/* Use full layout for now */
if (!pgio->pg_lseg)
if (!pgio->pg_lseg) {
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
0,
NFS4_MAX_UINT64,
IOMODE_READ,
GFP_KERNEL);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
return;
}
}
/* If no lseg, fall back to read through mds */
if (pgio->pg_lseg == NULL)
goto out_mds;
Expand Down Expand Up @@ -835,13 +841,19 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
int i;
int status;

if (!pgio->pg_lseg)
if (!pgio->pg_lseg) {
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
0,
NFS4_MAX_UINT64,
IOMODE_RW,
GFP_NOFS);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
return;
}
}
/* If no lseg, fall back to write through mds */
if (pgio->pg_lseg == NULL)
goto out_mds;
Expand Down Expand Up @@ -877,18 +889,25 @@ static unsigned int
ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req)
{
if (!pgio->pg_lseg)
if (!pgio->pg_lseg) {
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
0,
NFS4_MAX_UINT64,
IOMODE_RW,
GFP_NOFS);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
goto out;
}
}
if (pgio->pg_lseg)
return FF_LAYOUT_MIRROR_COUNT(pgio->pg_lseg);

/* no lseg means that pnfs is not in use, so no mirroring here */
nfs_pageio_reset_write_mds(pgio);
out:
return 1;
}

Expand Down
9 changes: 8 additions & 1 deletion fs/nfs/pagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,9 @@ static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio,

mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);

if (pgio->pg_error < 0)
return pgio->pg_error;

if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX)
return -EINVAL;

Expand Down Expand Up @@ -982,6 +985,8 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
} else {
if (desc->pg_ops->pg_init)
desc->pg_ops->pg_init(desc, req);
if (desc->pg_error < 0)
return 0;
mirror->pg_base = req->wb_pgbase;
}
if (!nfs_can_coalesce_requests(prev, req, desc))
Expand Down Expand Up @@ -1147,6 +1152,8 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
bytes = req->wb_bytes;

nfs_pageio_setup_mirroring(desc, req);
if (desc->pg_error < 0)
return 0;

for (midx = 0; midx < desc->pg_mirror_count; midx++) {
if (midx) {
Expand Down Expand Up @@ -1232,7 +1239,7 @@ int nfs_pageio_resend(struct nfs_pageio_descriptor *desc,
nfs_pageio_complete(desc);
if (!list_empty(&failed)) {
list_move(&failed, &hdr->pages);
return -EIO;
return desc->pg_error < 0 ? desc->pg_error : -EIO;
}
return 0;
}
Expand Down
24 changes: 18 additions & 6 deletions fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,14 +906,15 @@ send_layoutget(struct pnfs_layout_hdr *lo,

if (IS_ERR(lseg)) {
switch (PTR_ERR(lseg)) {
case -ENOMEM:
case -ERESTARTSYS:
case -EIO:
case -ENOSPC:
case -EROFS:
case -E2BIG:
break;
default:
/* remember that LAYOUTGET failed and suspend trying */
pnfs_layout_io_set_failed(lo, range->iomode);
return NULL;
}
return NULL;
} else
pnfs_layout_clear_fail_bit(lo,
pnfs_iomode_to_fail_bit(range->iomode));
Expand Down Expand Up @@ -1649,7 +1650,7 @@ pnfs_update_layout(struct inode *ino,
"(%s, offset: %llu, length: %llu)\n",
__func__, ino->i_sb->s_id,
(unsigned long long)NFS_FILEID(ino),
lseg == NULL ? "not found" : "found",
IS_ERR_OR_NULL(lseg) ? "not found" : "found",
iomode==IOMODE_RW ? "read/write" : "read-only",
(unsigned long long)pos,
(unsigned long long)count);
Expand Down Expand Up @@ -1828,6 +1829,11 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r
rd_size,
IOMODE_READ,
GFP_KERNEL);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
return;
}
}
/* If no lseg, fall back to read through mds */
if (pgio->pg_lseg == NULL)
Expand All @@ -1840,13 +1846,19 @@ void
pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
struct nfs_page *req, u64 wb_size)
{
if (pgio->pg_lseg == NULL)
if (pgio->pg_lseg == NULL) {
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
req_offset(req),
wb_size,
IOMODE_RW,
GFP_NOFS);
if (IS_ERR(pgio->pg_lseg)) {
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
pgio->pg_lseg = NULL;
return;
}
}
/* If no lseg, fall back to write through mds */
if (pgio->pg_lseg == NULL)
nfs_pageio_reset_write_mds(pgio);
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
pgm = &pgio.pg_mirrors[0];
NFS_I(inode)->read_io += pgm->pg_bytes_written;

return 0;
return pgio.pg_error < 0 ? pgio.pg_error : 0;
}

static void nfs_readpage_release(struct nfs_page *req)
Expand Down

0 comments on commit d600ad1

Please sign in to comment.