Loading fs/nfs/callback.h +2 −1 Original line number Diff line number Diff line Loading @@ -37,10 +37,11 @@ enum nfs4_callback_opnum { OP_CB_ILLEGAL = 10044, }; struct nfs4_slot; struct cb_process_state { __be32 drc_status; struct nfs_client *clp; u32 slotid; struct nfs4_slot *slot; u32 minorversion; struct net *net; }; Loading fs/nfs/callback_proc.c +10 −4 Original line number Diff line number Diff line Loading @@ -367,7 +367,7 @@ validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot, if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %u is a replay\n", __func__, args->csa_sequenceid); if (tbl->highest_used_slotid != NFS4_NO_SLOT) if (nfs4_test_locked_slot(tbl, slot->slot_nr)) return htonl(NFS4ERR_DELAY); /* Signal process_op to set this error on next op */ if (args->csa_cachethis == 0) Loading Loading @@ -476,12 +476,18 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, goto out_unlock; } status = htonl(NFS4ERR_BADSLOT); slot = nfs4_lookup_slot(tbl, args->csa_slotid); if (IS_ERR(slot)) goto out_unlock; status = validate_seqid(tbl, slot, args); if (status) goto out_unlock; cps->slotid = args->csa_slotid; tbl->highest_used_slotid = args->csa_slotid; if (!nfs4_try_to_lock_slot(tbl, slot)) { status = htonl(NFS4ERR_DELAY); goto out_unlock; } cps->slot = slot; memcpy(&res->csr_sessionid, &args->csa_sessionid, sizeof(res->csr_sessionid)); Loading fs/nfs/callback_xdr.c +7 −5 Original line number Diff line number Diff line Loading @@ -752,7 +752,8 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) return htonl(NFS_OK); } static void nfs4_callback_free_slot(struct nfs4_session *session) static void nfs4_callback_free_slot(struct nfs4_session *session, struct nfs4_slot *slot) { struct nfs4_slot_table *tbl = &session->bc_slot_table; Loading @@ -761,15 +762,17 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) * Let the state manager know callback processing done. * A single slot, so highest used slotid is either 0 or -1 */ tbl->highest_used_slotid = NFS4_NO_SLOT; nfs4_free_slot(tbl, slot); nfs4_slot_tbl_drain_complete(tbl); spin_unlock(&tbl->slot_tbl_lock); } static void nfs4_cb_free_slot(struct cb_process_state *cps) { if (cps->slotid != NFS4_NO_SLOT) nfs4_callback_free_slot(cps->clp->cl_session); if (cps->slot) { nfs4_callback_free_slot(cps->clp->cl_session, cps->slot); cps->slot = NULL; } } #else /* CONFIG_NFS_V4_1 */ Loading Loading @@ -893,7 +896,6 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r struct cb_process_state cps = { .drc_status = 0, .clp = NULL, .slotid = NFS4_NO_SLOT, .net = SVC_NET(rqstp), }; unsigned int nops = 0; Loading fs/nfs/nfs4session.c +42 −12 Original line number Diff line number Diff line Loading @@ -135,6 +135,43 @@ static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl, return ERR_PTR(-ENOMEM); } static void nfs4_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) { u32 slotid = slot->slot_nr; __set_bit(slotid, tbl->used_slots); if (slotid > tbl->highest_used_slotid || tbl->highest_used_slotid == NFS4_NO_SLOT) tbl->highest_used_slotid = slotid; slot->generation = tbl->generation; } /* * nfs4_try_to_lock_slot - Given a slot try to allocate it * * Note: must be called with the slot_tbl_lock held. */ bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) { if (nfs4_test_locked_slot(tbl, slot->slot_nr)) return false; nfs4_lock_slot(tbl, slot); return true; } /* * nfs4_lookup_slot - Find a slot but don't allocate it * * Note: must be called with the slot_tbl_lock held. */ struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid) { if (slotid <= tbl->max_slotid) return nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); return ERR_PTR(-E2BIG); } /* * nfs4_alloc_slot - efficiently look for a free slot * Loading @@ -153,18 +190,11 @@ struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) __func__, tbl->used_slots[0], tbl->highest_used_slotid, tbl->max_slotid + 1); slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1); if (slotid > tbl->max_slotid) goto out; if (slotid <= tbl->max_slotid) { ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); if (IS_ERR(ret)) goto out; __set_bit(slotid, tbl->used_slots); if (slotid > tbl->highest_used_slotid || tbl->highest_used_slotid == NFS4_NO_SLOT) tbl->highest_used_slotid = slotid; ret->generation = tbl->generation; out: if (!IS_ERR(ret)) nfs4_lock_slot(tbl, ret); } dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n", __func__, tbl->used_slots[0], tbl->highest_used_slotid, !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT); Loading fs/nfs/nfs4session.h +8 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, unsigned int max_reqs, const char *queue); extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); extern struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid); extern bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl, Loading @@ -88,6 +90,12 @@ static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl) return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); } static inline bool nfs4_test_locked_slot(const struct nfs4_slot_table *tbl, u32 slotid) { return !!test_bit(slotid, tbl->used_slots); } #if defined(CONFIG_NFS_V4_1) extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, u32 target_highest_slotid); Loading Loading
fs/nfs/callback.h +2 −1 Original line number Diff line number Diff line Loading @@ -37,10 +37,11 @@ enum nfs4_callback_opnum { OP_CB_ILLEGAL = 10044, }; struct nfs4_slot; struct cb_process_state { __be32 drc_status; struct nfs_client *clp; u32 slotid; struct nfs4_slot *slot; u32 minorversion; struct net *net; }; Loading
fs/nfs/callback_proc.c +10 −4 Original line number Diff line number Diff line Loading @@ -367,7 +367,7 @@ validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot, if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %u is a replay\n", __func__, args->csa_sequenceid); if (tbl->highest_used_slotid != NFS4_NO_SLOT) if (nfs4_test_locked_slot(tbl, slot->slot_nr)) return htonl(NFS4ERR_DELAY); /* Signal process_op to set this error on next op */ if (args->csa_cachethis == 0) Loading Loading @@ -476,12 +476,18 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, goto out_unlock; } status = htonl(NFS4ERR_BADSLOT); slot = nfs4_lookup_slot(tbl, args->csa_slotid); if (IS_ERR(slot)) goto out_unlock; status = validate_seqid(tbl, slot, args); if (status) goto out_unlock; cps->slotid = args->csa_slotid; tbl->highest_used_slotid = args->csa_slotid; if (!nfs4_try_to_lock_slot(tbl, slot)) { status = htonl(NFS4ERR_DELAY); goto out_unlock; } cps->slot = slot; memcpy(&res->csr_sessionid, &args->csa_sessionid, sizeof(res->csr_sessionid)); Loading
fs/nfs/callback_xdr.c +7 −5 Original line number Diff line number Diff line Loading @@ -752,7 +752,8 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) return htonl(NFS_OK); } static void nfs4_callback_free_slot(struct nfs4_session *session) static void nfs4_callback_free_slot(struct nfs4_session *session, struct nfs4_slot *slot) { struct nfs4_slot_table *tbl = &session->bc_slot_table; Loading @@ -761,15 +762,17 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) * Let the state manager know callback processing done. * A single slot, so highest used slotid is either 0 or -1 */ tbl->highest_used_slotid = NFS4_NO_SLOT; nfs4_free_slot(tbl, slot); nfs4_slot_tbl_drain_complete(tbl); spin_unlock(&tbl->slot_tbl_lock); } static void nfs4_cb_free_slot(struct cb_process_state *cps) { if (cps->slotid != NFS4_NO_SLOT) nfs4_callback_free_slot(cps->clp->cl_session); if (cps->slot) { nfs4_callback_free_slot(cps->clp->cl_session, cps->slot); cps->slot = NULL; } } #else /* CONFIG_NFS_V4_1 */ Loading Loading @@ -893,7 +896,6 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r struct cb_process_state cps = { .drc_status = 0, .clp = NULL, .slotid = NFS4_NO_SLOT, .net = SVC_NET(rqstp), }; unsigned int nops = 0; Loading
fs/nfs/nfs4session.c +42 −12 Original line number Diff line number Diff line Loading @@ -135,6 +135,43 @@ static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl, return ERR_PTR(-ENOMEM); } static void nfs4_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) { u32 slotid = slot->slot_nr; __set_bit(slotid, tbl->used_slots); if (slotid > tbl->highest_used_slotid || tbl->highest_used_slotid == NFS4_NO_SLOT) tbl->highest_used_slotid = slotid; slot->generation = tbl->generation; } /* * nfs4_try_to_lock_slot - Given a slot try to allocate it * * Note: must be called with the slot_tbl_lock held. */ bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) { if (nfs4_test_locked_slot(tbl, slot->slot_nr)) return false; nfs4_lock_slot(tbl, slot); return true; } /* * nfs4_lookup_slot - Find a slot but don't allocate it * * Note: must be called with the slot_tbl_lock held. */ struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid) { if (slotid <= tbl->max_slotid) return nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); return ERR_PTR(-E2BIG); } /* * nfs4_alloc_slot - efficiently look for a free slot * Loading @@ -153,18 +190,11 @@ struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) __func__, tbl->used_slots[0], tbl->highest_used_slotid, tbl->max_slotid + 1); slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1); if (slotid > tbl->max_slotid) goto out; if (slotid <= tbl->max_slotid) { ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); if (IS_ERR(ret)) goto out; __set_bit(slotid, tbl->used_slots); if (slotid > tbl->highest_used_slotid || tbl->highest_used_slotid == NFS4_NO_SLOT) tbl->highest_used_slotid = slotid; ret->generation = tbl->generation; out: if (!IS_ERR(ret)) nfs4_lock_slot(tbl, ret); } dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n", __func__, tbl->used_slots[0], tbl->highest_used_slotid, !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT); Loading
fs/nfs/nfs4session.h +8 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, unsigned int max_reqs, const char *queue); extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); extern struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid); extern bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl, Loading @@ -88,6 +90,12 @@ static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl) return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); } static inline bool nfs4_test_locked_slot(const struct nfs4_slot_table *tbl, u32 slotid) { return !!test_bit(slotid, tbl->used_slots); } #if defined(CONFIG_NFS_V4_1) extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, u32 target_highest_slotid); Loading