* [PATCH 1/3] NFSv4/flexfiles: report the intended opnum when DS connection setup fails
2026-08-13 18:07 [PATCH 0/3] pNFS/flexfiles: mirror instance error handling Benjamin Coddington
@ 2026-08-13 18:07 ` Benjamin Coddington
2026-08-13 18:07 ` [PATCH 2/3] pNFS: allow layout drivers to cancel I/O to a single device Benjamin Coddington
2026-08-13 18:07 ` [PATCH 3/3] NFSv4/flexfiles: only cancel I/O to a failed mirror instance Benjamin Coddington
2 siblings, 0 replies; 4+ messages in thread
From: Benjamin Coddington @ 2026-08-13 18:07 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs
When nfs4_ff_layout_prepare_ds() cannot establish a connection to a
data server, it records a device error with opnum OP_ILLEGAL, since no
operation ever made it to the wire. But servers can use the ff_ioerr4
opnum to distinguish failed read-class operations from write-class
operations when deciding how to recover the affected mirror -- a mirror
that may have missed writes needs to be brought back in sync, while one
that merely failed to serve a read does not. OP_ILLEGAL gives the
server nothing to act on.
Every caller of nfs4_ff_layout_prepare_ds() knows which operation it
was preparing to send, and the existing fail_return argument already
divides the callers along the same boundary (false for READ, true for
WRITE and COMMIT). Replace the boolean with the intended opnum, derive
the layout return decision from it, and report it in the tracked device
error instead of OP_ILLEGAL.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com>
---
fs/nfs/flexfilelayout/flexfilelayout.c | 10 +++++-----
fs/nfs/flexfilelayout/flexfilelayout.h | 2 +-
fs/nfs/flexfilelayout/flexfilelayoutdev.c | 14 ++++++++------
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 7fe8b91fa47c..2c30e62881a1 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -893,7 +893,7 @@ ff_layout_choose_ds_for_read(struct pnfs_layout_segment *lseg,
fls->stripe_unit,
fls->mirror_array[idx]->dss_count,
offset);
- ds = nfs4_ff_layout_prepare_ds(lseg, mirror, *dss_id, false);
+ ds = nfs4_ff_layout_prepare_ds(lseg, mirror, *dss_id, OP_READ);
if (IS_ERR(ds))
continue;
@@ -1135,7 +1135,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
mirror->dss_count,
req_offset(req));
ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, mirror,
- dss_id, true);
+ dss_id, OP_WRITE);
if (IS_ERR(ds)) {
if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))
goto out_mds;
@@ -2184,7 +2184,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
FF_LAYOUT_LSEG(lseg)->stripe_unit,
mirror->dss_count,
offset);
- ds = nfs4_ff_layout_prepare_ds(lseg, mirror, dss_id, false);
+ ds = nfs4_ff_layout_prepare_ds(lseg, mirror, dss_id, OP_READ);
if (IS_ERR(ds)) {
ds_fatal_error = nfs_error_is_fatal(PTR_ERR(ds));
goto out_failed;
@@ -2275,7 +2275,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
FF_LAYOUT_LSEG(lseg)->stripe_unit,
mirror->dss_count,
offset);
- ds = nfs4_ff_layout_prepare_ds(lseg, mirror, dss_id, true);
+ ds = nfs4_ff_layout_prepare_ds(lseg, mirror, dss_id, OP_WRITE);
if (IS_ERR(ds)) {
ds_fatal_error = nfs_error_is_fatal(PTR_ERR(ds));
goto out_failed;
@@ -2376,7 +2376,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
idx = calc_mirror_idx_from_commit(lseg, data->ds_commit_index);
mirror = FF_LAYOUT_COMP(lseg, idx);
dss_id = calc_dss_id_from_commit(lseg, data->ds_commit_index);
- ds = nfs4_ff_layout_prepare_ds(lseg, mirror, dss_id, true);
+ ds = nfs4_ff_layout_prepare_ds(lseg, mirror, dss_id, OP_COMMIT);
if (IS_ERR(ds))
goto out_err;
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h
index a5bd00f69e82..8e3a1e45ea68 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.h
+++ b/fs/nfs/flexfilelayout/flexfilelayout.h
@@ -252,7 +252,7 @@ struct nfs4_pnfs_ds *
nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
struct nfs4_ff_layout_mirror *mirror,
u32 dss_id,
- bool fail_return);
+ enum nfs_opnum4 opnum);
struct rpc_clnt *
nfs4_ff_find_or_create_ds_client(struct nfs4_ff_layout_mirror *mirror,
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 8be5c730e101..5920ba529a0b 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -359,7 +359,7 @@ ff_layout_init_mirror_ds(struct pnfs_layout_hdr *lo,
* @lseg: the layout segment we're operating on
* @mirror: layout mirror describing the DS to use
* @dss_id: DS stripe id to select stripe to use
- * @fail_return: return layout on connect failure?
+ * @opnum: operation this connection is being prepared for
*
* Try to prepare a DS connection to accept an RPC call. This involves
* selecting a mirror to use and connecting the client to it if it's not
@@ -367,8 +367,10 @@ ff_layout_init_mirror_ds(struct pnfs_layout_hdr *lo,
*
* Since we only need a single functioning mirror to satisfy a read, we don't
* want to return the layout if there is one. For writes though, any down
- * mirror should result in a LAYOUTRETURN. @fail_return is how we distinguish
- * between the two cases.
+ * mirror should result in a LAYOUTRETURN. @opnum is how we distinguish
+ * between the two cases. On failure, @opnum is also reported in the tracked
+ * device error so that the server can tell which class of I/O the client
+ * was unable to send to the mirror.
*
* Returns a pointer to a connected DS object on success or NULL on failure.
*/
@@ -376,7 +378,7 @@ struct nfs4_pnfs_ds *
nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
struct nfs4_ff_layout_mirror *mirror,
u32 dss_id,
- bool fail_return)
+ enum nfs_opnum4 opnum)
{
struct nfs4_pnfs_ds *ds;
struct inode *ino = lseg->pls_layout->plh_inode;
@@ -423,9 +425,9 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
mirror, dss_id, lseg->pls_range.offset,
lseg->pls_range.length, NFS4ERR_NXIO,
- OP_ILLEGAL, GFP_NOIO);
+ opnum, GFP_NOIO);
ff_layout_send_layouterror(lseg);
- if (fail_return || !ff_layout_has_available_ds(lseg))
+ if (opnum != OP_READ || !ff_layout_has_available_ds(lseg))
pnfs_error_mark_layout_for_return(ino, lseg);
ds = ERR_PTR(status);
out:
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/3] pNFS: allow layout drivers to cancel I/O to a single device
2026-08-13 18:07 [PATCH 0/3] pNFS/flexfiles: mirror instance error handling Benjamin Coddington
2026-08-13 18:07 ` [PATCH 1/3] NFSv4/flexfiles: report the intended opnum when DS connection setup fails Benjamin Coddington
@ 2026-08-13 18:07 ` Benjamin Coddington
2026-08-13 18:07 ` [PATCH 3/3] NFSv4/flexfiles: only cancel I/O to a failed mirror instance Benjamin Coddington
2 siblings, 0 replies; 4+ messages in thread
From: Benjamin Coddington @ 2026-08-13 18:07 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs
The ->cancel_io() layout operation cancels all in-flight I/O for a
layout segment that is being returned. When the return is triggered
by the failure of a single mirror instance, cancelling I/O to the
healthy mirrors is both unnecessary and harmful: requests that were
already transmitted cannot be un-sent, and will complete on the data
servers after the layout has been returned.
Give ->cancel_io() a device ID argument identifying the failed device,
and thread it through pnfs_error_mark_layout_for_return() and
pnfs_mark_matching_lsegs_return(). The flexfiles implementation
compares it against the raw device ID from the layout, so that it can
identify the failed mirror instance even when its device ID node was
never instantiated.
A NULL device ID preserves the existing cancel-everything behavior,
and all callers pass NULL for now, so this patch makes no change in
behavior.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com>
---
fs/nfs/blocklayout/blocklayout.c | 6 +++--
fs/nfs/callback_proc.c | 2 +-
fs/nfs/filelayout/filelayout.c | 4 +--
fs/nfs/flexfilelayout/flexfilelayout.c | 16 +++++++-----
fs/nfs/flexfilelayout/flexfilelayoutdev.c | 2 +-
fs/nfs/pnfs.c | 32 ++++++++++++++---------
fs/nfs/pnfs.h | 14 ++++++----
7 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index d54a141a89b3..d86702e604f9 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -859,7 +859,8 @@ bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
if (pgio->pg_lseg &&
test_bit(NFS_LSEG_UNAVAILABLE, &pgio->pg_lseg->pls_flags)) {
- pnfs_error_mark_layout_for_return(pgio->pg_inode, pgio->pg_lseg);
+ pnfs_error_mark_layout_for_return(pgio->pg_inode, pgio->pg_lseg,
+ NULL);
pnfs_set_lo_fail(pgio->pg_lseg);
nfs_pageio_reset_read_mds(pgio);
}
@@ -921,7 +922,8 @@ bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
if (pgio->pg_lseg &&
test_bit(NFS_LSEG_UNAVAILABLE, &pgio->pg_lseg->pls_flags)) {
- pnfs_error_mark_layout_for_return(pgio->pg_inode, pgio->pg_lseg);
+ pnfs_error_mark_layout_for_return(pgio->pg_inode, pgio->pg_lseg,
+ NULL);
pnfs_set_lo_fail(pgio->pg_lseg);
nfs_pageio_reset_write_mds(pgio);
}
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 3fb10c8e4271..ddc8736100e1 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -292,7 +292,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
switch (pnfs_mark_matching_lsegs_return(lo, &free_me_list,
&args->cbl_range,
be32_to_cpu(args->cbl_stateid.seqid),
- args->cbl_layoutchanged)) {
+ args->cbl_layoutchanged, NULL)) {
case 0:
case -EBUSY:
/* There are layout segments that need to be returned */
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 72e20b56fbc7..96c0398b0b4c 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -186,7 +186,7 @@ static int filelayout_async_handle_error(struct rpc_task *task,
dprintk("%s DS connection error %d\n", __func__,
task->tk_status);
nfs4_mark_deviceid_unavailable(devid);
- pnfs_error_mark_layout_for_return(inode, lseg);
+ pnfs_error_mark_layout_for_return(inode, lseg, NULL);
pnfs_set_lo_fail(lseg);
rpc_wake_up(&tbl->slot_tbl_waitq);
fallthrough;
@@ -856,7 +856,7 @@ fl_pnfs_update_layout(struct inode *ino,
status = filelayout_check_deviceid(lo, fl, gfp_flags);
if (status) {
- pnfs_error_mark_layout_for_return(ino, lseg);
+ pnfs_error_mark_layout_for_return(ino, lseg, NULL);
pnfs_set_lo_fail(lseg);
pnfs_put_lseg(lseg);
lseg = NULL;
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 2c30e62881a1..b0c90e6cdccb 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1282,7 +1282,7 @@ static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr)
ds = ff_layout_choose_any_ds_for_read(hdr->lseg, idx, &new_idx,
hdr->args.offset, &dss_id);
if (IS_ERR(ds))
- pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg);
+ pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg, NULL);
else
ff_layout_send_layouterror(hdr->lseg);
pnfs_read_resend_pnfs(hdr, new_idx);
@@ -1293,7 +1293,7 @@ static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
struct rpc_task *task = &hdr->task;
pnfs_layoutcommit_inode(hdr->inode, false);
- pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg);
+ pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg, NULL);
if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
dprintk("%s Reset task %5u for i/o through MDS "
@@ -1590,7 +1590,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
fallthrough;
default:
pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,
- lseg);
+ lseg, NULL);
}
out:
@@ -2244,7 +2244,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
* FF_FLAGS_NO_IO_THRU_MDS: force fresh LAYOUTGET,
* never fall through to MDS I/O.
*/
- pnfs_error_mark_layout_for_return(hdr->inode, lseg);
+ pnfs_error_mark_layout_for_return(hdr->inode, lseg, NULL);
return PNFS_TRY_AGAIN;
}
trace_pnfs_mds_fallback_read_pagelist(hdr->inode,
@@ -2337,7 +2337,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
* FF_FLAGS_NO_IO_THRU_MDS: force fresh LAYOUTGET,
* never fall through to MDS I/O.
*/
- pnfs_error_mark_layout_for_return(hdr->inode, lseg);
+ pnfs_error_mark_layout_for_return(hdr->inode, lseg, NULL);
return PNFS_TRY_AGAIN;
}
trace_pnfs_mds_fallback_write_pagelist(hdr->inode,
@@ -2459,7 +2459,8 @@ static bool ff_layout_match_io(const struct rpc_task *task, const void *data)
return false;
}
-static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
+static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg,
+ const struct nfs4_deviceid *devid)
{
struct nfs4_ff_layout_segment *flseg = FF_LAYOUT_LSEG(lseg);
struct nfs4_ff_layout_mirror *mirror;
@@ -2472,6 +2473,9 @@ static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
for (idx = 0; idx < flseg->mirror_array_cnt; idx++) {
mirror = flseg->mirror_array[idx];
for (dss_id = 0; dss_id < mirror->dss_count; dss_id++) {
+ if (devid && memcmp(&mirror->dss[dss_id].devid, devid,
+ sizeof(*devid)) != 0)
+ continue;
mirror_ds = mirror->dss[dss_id].mirror_ds;
if (IS_ERR_OR_NULL(mirror_ds))
continue;
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 5920ba529a0b..33ee3ed1f546 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -428,7 +428,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
opnum, GFP_NOIO);
ff_layout_send_layouterror(lseg);
if (opnum != OP_READ || !ff_layout_has_available_ds(lseg))
- pnfs_error_mark_layout_for_return(ino, lseg);
+ pnfs_error_mark_layout_for_return(ino, lseg, NULL);
ds = ERR_PTR(status);
out:
return ds;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 9a08fd076e0a..c4ea2ffd2f01 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -433,7 +433,7 @@ bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst,
}
/* Try to update the seqid to the most recent */
err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0,
- true);
+ true, NULL);
if (err != -EBUSY) {
dst->seqid = lo->plh_stateid.seqid;
*dst_range = range;
@@ -487,7 +487,8 @@ static int pnfs_mark_layout_stateid_return(struct pnfs_layout_hdr *lo,
.length = NFS4_MAX_UINT64,
};
- return pnfs_mark_matching_lsegs_return(lo, lseg_list, &range, seq, true);
+ return pnfs_mark_matching_lsegs_return(lo, lseg_list, &range, seq, true,
+ NULL);
}
static int
@@ -525,7 +526,7 @@ pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
spin_lock(&inode->i_lock);
pnfs_layout_set_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
- pnfs_mark_matching_lsegs_return(lo, &head, &range, 0, true);
+ pnfs_mark_matching_lsegs_return(lo, &head, &range, 0, true, NULL);
spin_unlock(&inode->i_lock);
pnfs_free_lseg_list(&head);
dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__,
@@ -740,7 +741,7 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
if (mark_lseg_invalid(lseg, tmp_list))
continue;
remaining++;
- pnfs_lseg_cancel_io(server, lseg);
+ pnfs_lseg_cancel_io(server, lseg, NULL);
}
dprintk("%s:Return %i\n", __func__, remaining);
return remaining;
@@ -1462,7 +1463,7 @@ _pnfs_return_layout(struct inode *ino)
}
valid_layout = pnfs_layout_is_valid(lo);
pnfs_clear_layoutcommit(ino, &tmp_list);
- pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0, true);
+ pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0, true, NULL);
/* Don't send a LAYOUTRETURN if list was initially empty */
@@ -2616,7 +2617,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
.iomode = IOMODE_ANY,
.length = NFS4_MAX_UINT64,
};
- pnfs_mark_matching_lsegs_return(lo, &free_me, &range, 0, true);
+ pnfs_mark_matching_lsegs_return(lo, &free_me, &range, 0, true,
+ NULL);
goto out_forget;
} else {
/* We have a completely new layout */
@@ -2648,6 +2650,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
* @return_range: describe layout segment ranges to be returned
* @seq: stateid seqid to match
* @cancel_io: signal io be cancelled
+ * @devid: only cancel io directed at this device (all devices if NULL)
*
* This function is mainly intended for use by layoutrecall. It attempts
* to free the layout segment immediately, or else to mark it for return
@@ -2662,7 +2665,8 @@ int
pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
struct list_head *tmp_list,
const struct pnfs_layout_range *return_range,
- u32 seq, bool cancel_io)
+ u32 seq, bool cancel_io,
+ const struct nfs4_deviceid *devid)
{
struct pnfs_layout_segment *lseg, *next;
struct nfs_server *server = NFS_SERVER(lo->plh_inode);
@@ -2689,7 +2693,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
remaining++;
set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
if (cancel_io)
- pnfs_lseg_cancel_io(server, lseg);
+ pnfs_lseg_cancel_io(server, lseg, devid);
}
if (remaining) {
@@ -2707,7 +2711,8 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
static void
pnfs_mark_layout_for_return(struct inode *inode,
- const struct pnfs_layout_range *range)
+ const struct pnfs_layout_range *range,
+ const struct nfs4_deviceid *devid)
{
struct pnfs_layout_hdr *lo;
bool return_now = false;
@@ -2725,7 +2730,7 @@ pnfs_mark_layout_for_return(struct inode *inode,
* for how it works.
*/
if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, range, 0,
- true) != -EBUSY) {
+ true, devid) != -EBUSY) {
const struct cred *cred;
nfs4_stateid stateid;
enum pnfs_iomode iomode;
@@ -2742,7 +2747,8 @@ pnfs_mark_layout_for_return(struct inode *inode,
}
void pnfs_error_mark_layout_for_return(struct inode *inode,
- struct pnfs_layout_segment *lseg)
+ struct pnfs_layout_segment *lseg,
+ const struct nfs4_deviceid *devid)
{
struct pnfs_layout_range range = {
.iomode = lseg->pls_range.iomode,
@@ -2750,7 +2756,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
.length = NFS4_MAX_UINT64,
};
- pnfs_mark_layout_for_return(inode, &range);
+ pnfs_mark_layout_for_return(inode, &range, devid);
}
EXPORT_SYMBOL_GPL(pnfs_error_mark_layout_for_return);
@@ -2840,7 +2846,7 @@ static int pnfs_layout_return_unused_byserver(struct nfs_server *server,
pnfs_get_layout_hdr(lo);
pnfs_set_plh_return_info(lo, range->iomode, 0);
if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
- range, 0, true) != 0 ||
+ range, 0, true, NULL) != 0 ||
!pnfs_prepare_layoutreturn(lo, &stateid, &cred, &iomode)) {
spin_unlock(&inode->i_lock);
rcu_read_unlock();
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index bab81f769636..ccc65ad0e9af 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -177,7 +177,8 @@ struct pnfs_layoutdriver_type {
int (*prepare_layoutcommit) (struct nfs4_layoutcommit_args *args);
int (*prepare_layoutstats) (struct nfs42_layoutstat_args *args);
- void (*cancel_io)(struct pnfs_layout_segment *lseg);
+ void (*cancel_io)(struct pnfs_layout_segment *lseg,
+ const struct nfs4_deviceid *devid);
};
struct pnfs_commit_ops {
@@ -300,7 +301,8 @@ int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
int pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
struct list_head *tmp_list,
const struct pnfs_layout_range *recall_range,
- u32 seq, bool cancel_io);
+ u32 seq, bool cancel_io,
+ const struct nfs4_deviceid *devid);
int pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
struct list_head *lseg_list);
bool pnfs_roc(struct inode *ino, struct nfs4_layoutreturn_args *args,
@@ -350,7 +352,8 @@ int pnfs_read_done_resend_to_mds(struct nfs_pgio_header *);
int pnfs_write_done_resend_to_mds(struct nfs_pgio_header *);
struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
void pnfs_error_mark_layout_for_return(struct inode *inode,
- struct pnfs_layout_segment *lseg);
+ struct pnfs_layout_segment *lseg,
+ const struct nfs4_deviceid *devid);
void pnfs_layout_return_unused_byclid(struct nfs_client *clp,
enum pnfs_iomode iomode);
int pnfs_layout_handle_reboot(struct nfs_client *clp);
@@ -689,10 +692,11 @@ pnfs_lseg_request_intersecting(struct pnfs_layout_segment *lseg, struct nfs_page
}
static inline void pnfs_lseg_cancel_io(struct nfs_server *server,
- struct pnfs_layout_segment *lseg)
+ struct pnfs_layout_segment *lseg,
+ const struct nfs4_deviceid *devid)
{
if (server->pnfs_curr_ld->cancel_io)
- server->pnfs_curr_ld->cancel_io(lseg);
+ server->pnfs_curr_ld->cancel_io(lseg, devid);
}
extern unsigned int layoutstats_timer;
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread