Loading fs/nfs/nfs4proc.c +1 −0 Original line number Diff line number Diff line Loading @@ -7540,6 +7540,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata) return; if (pnfs_choose_layoutget_stateid(&lgp->args.stateid, NFS_I(lgp->args.inode)->layout, &lgp->args.range, lgp->args.ctx->state)) { rpc_exit(task, NFS4_OK); } Loading fs/nfs/pnfs.c +18 −5 Original line number Diff line number Diff line Loading @@ -740,25 +740,37 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo, return !pnfs_seqid_is_newer(seqid, lo->plh_barrier); } static bool pnfs_layout_returning(const struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range) { return test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) && (lo->plh_return_iomode == IOMODE_ANY || lo->plh_return_iomode == range->iomode); } /* lget is set to 1 if called from inside send_layoutget call chain */ static bool pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, int lget) pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range, int lget) { return lo->plh_block_lgets || test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || (list_empty(&lo->plh_segs) && (atomic_read(&lo->plh_outstanding) > lget)); (atomic_read(&lo->plh_outstanding) > lget)) || pnfs_layout_returning(lo, range); } int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range, struct nfs4_state *open_state) { int status = 0; dprintk("--> %s\n", __func__); spin_lock(&lo->plh_inode->i_lock); if (pnfs_layoutgets_blocked(lo, 1)) { if (pnfs_layoutgets_blocked(lo, range, 1)) { status = -EAGAIN; } else if (!nfs4_valid_open_stateid(open_state)) { status = -EBADF; Loading Loading @@ -1192,6 +1204,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, list_for_each_entry(lseg, &lo->plh_segs, pls_list) { if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && !test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags) && pnfs_lseg_range_match(&lseg->pls_range, range)) { ret = pnfs_get_lseg(lseg); break; Loading Loading @@ -1351,7 +1364,7 @@ lookup_again: goto out_unlock; } if (pnfs_layoutgets_blocked(lo, 0)) if (pnfs_layoutgets_blocked(lo, &arg, 0)) goto out_unlock; atomic_inc(&lo->plh_outstanding); spin_unlock(&ino->i_lock); Loading Loading @@ -1432,7 +1445,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) goto out_forget_reply; } if (pnfs_layoutgets_blocked(lo, 1)) { if (pnfs_layoutgets_blocked(lo, &lgp->args.range, 1)) { dprintk("%s forget reply due to state\n", __func__); goto out_forget_reply; } Loading fs/nfs/pnfs.h +1 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, bool update_barrier); int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range, struct nfs4_state *open_state); int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, Loading Loading
fs/nfs/nfs4proc.c +1 −0 Original line number Diff line number Diff line Loading @@ -7540,6 +7540,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata) return; if (pnfs_choose_layoutget_stateid(&lgp->args.stateid, NFS_I(lgp->args.inode)->layout, &lgp->args.range, lgp->args.ctx->state)) { rpc_exit(task, NFS4_OK); } Loading
fs/nfs/pnfs.c +18 −5 Original line number Diff line number Diff line Loading @@ -740,25 +740,37 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo, return !pnfs_seqid_is_newer(seqid, lo->plh_barrier); } static bool pnfs_layout_returning(const struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range) { return test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) && (lo->plh_return_iomode == IOMODE_ANY || lo->plh_return_iomode == range->iomode); } /* lget is set to 1 if called from inside send_layoutget call chain */ static bool pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, int lget) pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range, int lget) { return lo->plh_block_lgets || test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || (list_empty(&lo->plh_segs) && (atomic_read(&lo->plh_outstanding) > lget)); (atomic_read(&lo->plh_outstanding) > lget)) || pnfs_layout_returning(lo, range); } int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range, struct nfs4_state *open_state) { int status = 0; dprintk("--> %s\n", __func__); spin_lock(&lo->plh_inode->i_lock); if (pnfs_layoutgets_blocked(lo, 1)) { if (pnfs_layoutgets_blocked(lo, range, 1)) { status = -EAGAIN; } else if (!nfs4_valid_open_stateid(open_state)) { status = -EBADF; Loading Loading @@ -1192,6 +1204,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, list_for_each_entry(lseg, &lo->plh_segs, pls_list) { if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && !test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags) && pnfs_lseg_range_match(&lseg->pls_range, range)) { ret = pnfs_get_lseg(lseg); break; Loading Loading @@ -1351,7 +1364,7 @@ lookup_again: goto out_unlock; } if (pnfs_layoutgets_blocked(lo, 0)) if (pnfs_layoutgets_blocked(lo, &arg, 0)) goto out_unlock; atomic_inc(&lo->plh_outstanding); spin_unlock(&ino->i_lock); Loading Loading @@ -1432,7 +1445,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) goto out_forget_reply; } if (pnfs_layoutgets_blocked(lo, 1)) { if (pnfs_layoutgets_blocked(lo, &lgp->args.range, 1)) { dprintk("%s forget reply due to state\n", __func__); goto out_forget_reply; } Loading
fs/nfs/pnfs.h +1 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, bool update_barrier); int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, struct pnfs_layout_range *range, struct nfs4_state *open_state); int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, struct list_head *tmp_list, Loading