diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index f5cf76d36367..3fb10c8e4271 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -291,7 +291,8 @@ static u32 initiate_file_draining(struct nfs_client *clp, pnfs_set_layout_stateid(lo, &args->cbl_stateid, NULL, true); switch (pnfs_mark_matching_lsegs_return(lo, &free_me_list, &args->cbl_range, - be32_to_cpu(args->cbl_stateid.seqid))) { + be32_to_cpu(args->cbl_stateid.seqid), + args->cbl_layoutchanged)) { case 0: case -EBUSY: /* There are layout segments that need to be returned */ diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 99c50a1fde2b..9a08fd076e0a 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -432,7 +432,8 @@ bool nfs4_layout_refresh_old_stateid(nfs4_stateid *dst, goto out; } /* Try to update the seqid to the most recent */ - err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0); + err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0, + true); if (err != -EBUSY) { dst->seqid = lo->plh_stateid.seqid; *dst_range = range; @@ -486,7 +487,7 @@ 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); + return pnfs_mark_matching_lsegs_return(lo, lseg_list, &range, seq, true); } static int @@ -524,7 +525,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); + pnfs_mark_matching_lsegs_return(lo, &head, &range, 0, true); spin_unlock(&inode->i_lock); pnfs_free_lseg_list(&head); dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__, @@ -1461,7 +1462,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); + pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0, true); /* Don't send a LAYOUTRETURN if list was initially empty */ @@ -2615,7 +2616,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) .iomode = IOMODE_ANY, .length = NFS4_MAX_UINT64, }; - pnfs_mark_matching_lsegs_return(lo, &free_me, &range, 0); + pnfs_mark_matching_lsegs_return(lo, &free_me, &range, 0, true); goto out_forget; } else { /* We have a completely new layout */ @@ -2646,6 +2647,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) * @tmp_list: list header to be used with pnfs_free_lseg_list() * @return_range: describe layout segment ranges to be returned * @seq: stateid seqid to match + * @cancel_io: signal io be cancelled * * This function is mainly intended for use by layoutrecall. It attempts * to free the layout segment immediately, or else to mark it for return @@ -2660,7 +2662,7 @@ 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) + u32 seq, bool cancel_io) { struct pnfs_layout_segment *lseg, *next; struct nfs_server *server = NFS_SERVER(lo->plh_inode); @@ -2686,7 +2688,8 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, continue; remaining++; set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags); - pnfs_lseg_cancel_io(server, lseg); + if (cancel_io) + pnfs_lseg_cancel_io(server, lseg); } if (remaining) { @@ -2721,7 +2724,8 @@ pnfs_mark_layout_for_return(struct inode *inode, * segments at hand when sending layoutreturn. See pnfs_put_lseg() * for how it works. */ - if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, range, 0) != -EBUSY) { + if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, range, 0, + true) != -EBUSY) { const struct cred *cred; nfs4_stateid stateid; enum pnfs_iomode iomode; @@ -2836,7 +2840,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) != 0 || + range, 0, true) != 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 eb39859c216c..673c2b244978 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -300,7 +300,7 @@ 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); + u32 seq, bool cancel_io); 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,