For a CB_NOTIFY operation, we need to stop processing the callback
if an allocation fails. Change the ->prepare callback operation to
return true if processing should continue, and false otherwise.

Signed-off-by: Jeff Layton <[email protected]>
---
 fs/nfsd/nfs4callback.c | 5 ++++-
 fs/nfsd/nfs4layouts.c  | 3 ++-
 fs/nfsd/nfs4state.c    | 6 ++++--
 fs/nfsd/state.h        | 6 +++---
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 
e00b2aea8da2b93f366d88888f404734953f1942..d13a4819d764269338f2b05a05f975c037e589af
 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -1739,7 +1739,10 @@ nfsd4_run_cb_work(struct work_struct *work)
 
        if (!test_and_clear_bit(NFSD4_CALLBACK_REQUEUE, &cb->cb_flags)) {
                if (cb->cb_ops && cb->cb_ops->prepare)
-                       cb->cb_ops->prepare(cb);
+                       if (!cb->cb_ops->prepare(cb)) {
+                               nfsd41_destroy_cb(cb);
+                               return;
+                       }
        }
 
        cb->cb_msg.rpc_cred = clp->cl_cb_cred;
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 
683bd1130afe298f9df774684192c89f68102b72..1916e5541153126edc357cfeeff9ce30461b69c0
 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -652,7 +652,7 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls, struct 
nfsd_file *file)
        }
 }
 
-static void
+static bool
 nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
 {
        struct nfs4_layout_stateid *ls =
@@ -661,6 +661,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb)
        mutex_lock(&ls->ls_mutex);
        nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
        mutex_unlock(&ls->ls_mutex);
+       return true;
 }
 
 static int
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 
eac9e9360e568caf1f615d230cff39e022107f12..517ba5595da3be5e130e1978ba30235496efbe01
 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -361,12 +361,13 @@ remove_blocked_locks(struct nfs4_lockowner *lo)
        }
 }
 
-static void
+static bool
 nfsd4_cb_notify_lock_prepare(struct nfsd4_callback *cb)
 {
        struct nfsd4_blocked_lock       *nbl = container_of(cb,
                                                struct nfsd4_blocked_lock, 
nbl_cb);
        locks_delete_block(&nbl->nbl_lock);
+       return true;
 }
 
 static int
@@ -5450,7 +5451,7 @@ bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp, 
struct inode *inode)
        return timeo > 0;
 }
 
-static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
+static bool nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
 {
        struct nfs4_delegation *dp = cb_to_delegation(cb);
        struct nfsd_net *nn = net_generic(dp->dl_stid.sc_client->net,
@@ -5471,6 +5472,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback 
*cb)
                list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
        }
        spin_unlock(&state_lock);
+       return true;
 }
 
 static int nfsd4_cb_recall_done(struct nfsd4_callback *cb,
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 
b052c1effdc5356487c610db9728df8ecfe851d4..bacb9f9eff3aaf7076d53f06826026569a567bd9
 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -98,9 +98,9 @@ struct nfsd4_callback {
 };
 
 struct nfsd4_callback_ops {
-       void (*prepare)(struct nfsd4_callback *);
-       int (*done)(struct nfsd4_callback *, struct rpc_task *);
-       void (*release)(struct nfsd4_callback *);
+       bool (*prepare)(struct nfsd4_callback *cb);
+       int (*done)(struct nfsd4_callback *cb, struct rpc_task *task);
+       void (*release)(struct nfsd4_callback *cb);
        uint32_t opcode;
 };
 

-- 
2.51.0


Reply via email to