From: Sasha Levin Date: Tue, 7 Jul 2020 22:27:41 +0000 (-0400) Subject: Fix up nfsd4 on 5.7 and 5.4 X-Git-Tag: v4.4.230~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e77658bc31c88bef74ceed09f6ffdc00540f7544;p=thirdparty%2Fkernel%2Fstable-queue.git Fix up nfsd4 on 5.7 and 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/kthread-save-thread-function.patch b/queue-5.4/kthread-save-thread-function.patch deleted file mode 100644 index f11a4dd5469..00000000000 --- a/queue-5.4/kthread-save-thread-function.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 8fc259ae3d756536fe0d3d5a105f8b5ff860dbc9 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 6 May 2020 12:09:34 -0400 -Subject: kthread: save thread function - -From: J. Bruce Fields - -[ Upstream commit 52782c92ac85c4e393eb4a903a62e6c24afa633f ] - -It's handy to keep the kthread_fn just as a unique cookie to identify -classes of kthreads. E.g. if you can verify that a given task is -running your thread_fn, then you may know what sort of type kthread_data -points to. - -We'll use this in nfsd to pass some information into the vfs. Note it -will need kthread_data() exported too. - -Original-patch-by: Tejun Heo -Signed-off-by: J. Bruce Fields -Signed-off-by: Sasha Levin ---- - include/linux/kthread.h | 1 + - kernel/kthread.c | 17 +++++++++++++++++ - 2 files changed, 18 insertions(+) - -diff --git a/include/linux/kthread.h b/include/linux/kthread.h -index 0f9da966934e2..59bbc63ff8637 100644 ---- a/include/linux/kthread.h -+++ b/include/linux/kthread.h -@@ -57,6 +57,7 @@ bool kthread_should_stop(void); - bool kthread_should_park(void); - bool __kthread_should_park(struct task_struct *k); - bool kthread_freezable_should_stop(bool *was_frozen); -+void *kthread_func(struct task_struct *k); - void *kthread_data(struct task_struct *k); - void *kthread_probe_data(struct task_struct *k); - int kthread_park(struct task_struct *k); -diff --git a/kernel/kthread.c b/kernel/kthread.c -index b262f47046ca4..543dff6b576c7 100644 ---- a/kernel/kthread.c -+++ b/kernel/kthread.c -@@ -46,6 +46,7 @@ struct kthread_create_info - struct kthread { - unsigned long flags; - unsigned int cpu; -+ int (*threadfn)(void *); - void *data; - struct completion parked; - struct completion exited; -@@ -152,6 +153,20 @@ bool kthread_freezable_should_stop(bool *was_frozen) - } - EXPORT_SYMBOL_GPL(kthread_freezable_should_stop); - -+/** -+ * kthread_func - return the function specified on kthread creation -+ * @task: kthread task in question -+ * -+ * Returns NULL if the task is not a kthread. -+ */ -+void *kthread_func(struct task_struct *task) -+{ -+ if (task->flags & PF_KTHREAD) -+ return to_kthread(task)->threadfn; -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(kthread_func); -+ - /** - * kthread_data - return data value specified on kthread creation - * @task: kthread task in question -@@ -164,6 +179,7 @@ void *kthread_data(struct task_struct *task) - { - return to_kthread(task)->data; - } -+EXPORT_SYMBOL_GPL(kthread_data); - - /** - * kthread_probe_data - speculative version of kthread_data() -@@ -237,6 +253,7 @@ static int kthread(void *_create) - do_exit(-ENOMEM); - } - -+ self->threadfn = threadfn; - self->data = data; - init_completion(&self->exited); - init_completion(&self->parked); --- -2.25.1 - diff --git a/queue-5.4/nfsd-clients-don-t-need-to-break-their-own-delegatio.patch b/queue-5.4/nfsd-clients-don-t-need-to-break-their-own-delegatio.patch deleted file mode 100644 index 7951037a96c..00000000000 --- a/queue-5.4/nfsd-clients-don-t-need-to-break-their-own-delegatio.patch +++ /dev/null @@ -1,187 +0,0 @@ -From aaa9f6e532dc34b60ba7390a9d6d9c3dd22759a2 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 28 Jul 2017 16:35:15 -0400 -Subject: nfsd: clients don't need to break their own delegations - -From: J. Bruce Fields - -[ Upstream commit 28df3d1539de5090f7916f6fff03891b67f366f4 ] - -We currently revoke read delegations on any write open or any operation -that modifies file data or metadata (including rename, link, and -unlink). But if the delegation in question is the only read delegation -and is held by the client performing the operation, that's not really -necessary. - -It's not always possible to prevent this in the NFSv4.0 case, because -there's not always a way to determine which client an NFSv4.0 delegation -came from. (In theory we could try to guess this from the transport -layer, e.g., by assuming all traffic on a given TCP connection comes -from the same client. But that's not really correct.) - -In the NFSv4.1 case the session layer always tells us the client. - -This patch should remove such self-conflicts in all cases where we can -reliably determine the client from the compound. - -To do that we need to track "who" is performing a given (possibly -lease-breaking) file operation. We're doing that by storing the -information in the svc_rqst and using kthread_data() to map the current -task back to a svc_rqst. - -Signed-off-by: J. Bruce Fields -Signed-off-by: Sasha Levin ---- - Documentation/filesystems/locking.rst | 2 ++ - fs/locks.c | 3 +++ - fs/nfsd/nfs4proc.c | 2 ++ - fs/nfsd/nfs4state.c | 14 ++++++++++++++ - fs/nfsd/nfsd.h | 2 ++ - fs/nfsd/nfssvc.c | 6 ++++++ - include/linux/fs.h | 1 + - include/linux/sunrpc/svc.h | 1 + - 8 files changed, 31 insertions(+) - -diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst -index fc3a0704553cf..b5f8d15a30fb7 100644 ---- a/Documentation/filesystems/locking.rst -+++ b/Documentation/filesystems/locking.rst -@@ -425,6 +425,7 @@ prototypes:: - int (*lm_grant)(struct file_lock *, struct file_lock *, int); - void (*lm_break)(struct file_lock *); /* break_lease callback */ - int (*lm_change)(struct file_lock **, int); -+ bool (*lm_breaker_owns_lease)(struct file_lock *); - - locking rules: - -@@ -435,6 +436,7 @@ lm_notify: yes yes no - lm_grant: no no no - lm_break: yes no no - lm_change yes no no -+lm_breaker_owns_lease: no no no - ========== ============= ================= ========= - - buffer_head -diff --git a/fs/locks.c b/fs/locks.c -index b8a31c1c4fff3..a3f186846e93e 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -1557,6 +1557,9 @@ static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker) - { - bool rc; - -+ if (lease->fl_lmops->lm_breaker_owns_lease -+ && lease->fl_lmops->lm_breaker_owns_lease(lease)) -+ return false; - if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT)) { - rc = false; - goto trace; -diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c -index 4798667af647c..96fa2837d3cfb 100644 ---- a/fs/nfsd/nfs4proc.c -+++ b/fs/nfsd/nfs4proc.c -@@ -1961,6 +1961,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) - goto encode_op; - } - -+ rqstp->rq_lease_breaker = (void **)&cstate->clp; -+ - trace_nfsd_compound(rqstp, args->opcnt); - while (!status && resp->opcnt < args->opcnt) { - op = &args->ops[resp->opcnt++]; -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 8650a97e2ba96..1e8f5e281bb53 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -4464,6 +4464,19 @@ nfsd_break_deleg_cb(struct file_lock *fl) - return ret; - } - -+static bool nfsd_breaker_owns_lease(struct file_lock *fl) -+{ -+ struct nfs4_delegation *dl = fl->fl_owner; -+ struct svc_rqst *rqst; -+ struct nfs4_client *clp; -+ -+ if (!i_am_nfsd()) -+ return NULL; -+ rqst = kthread_data(current); -+ clp = *(rqst->rq_lease_breaker); -+ return dl->dl_stid.sc_client == clp; -+} -+ - static int - nfsd_change_deleg_cb(struct file_lock *onlist, int arg, - struct list_head *dispose) -@@ -4475,6 +4488,7 @@ nfsd_change_deleg_cb(struct file_lock *onlist, int arg, - } - - static const struct lock_manager_operations nfsd_lease_mng_ops = { -+ .lm_breaker_owns_lease = nfsd_breaker_owns_lease, - .lm_break = nfsd_break_deleg_cb, - .lm_change = nfsd_change_deleg_cb, - }; -diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index af2947551e9ce..7a835fb7d79f7 100644 ---- a/fs/nfsd/nfsd.h -+++ b/fs/nfsd/nfsd.h -@@ -87,6 +87,8 @@ int nfsd_pool_stats_release(struct inode *, struct file *); - - void nfsd_destroy(struct net *net); - -+bool i_am_nfsd(void); -+ - struct nfsdfs_client { - struct kref cl_ref; - void (*cl_release)(struct kref *kref); -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index e8bee8ff30c59..cb7f0aa9a3b05 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -590,6 +590,11 @@ static const struct svc_serv_ops nfsd_thread_sv_ops = { - .svo_module = THIS_MODULE, - }; - -+bool i_am_nfsd() -+{ -+ return kthread_func(current) == nfsd; -+} -+ - int nfsd_create_serv(struct net *net) - { - int error; -@@ -997,6 +1002,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - *statp = rpc_garbage_args; - return 1; - } -+ rqstp->rq_lease_breaker = NULL; - /* - * Give the xdr decoder a chance to change this if it wants - * (necessary in the NFSv4.0 compound case) -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 5bd384dbdca58..4b5b7667405d8 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1040,6 +1040,7 @@ struct lock_manager_operations { - bool (*lm_break)(struct file_lock *); - int (*lm_change)(struct file_lock *, int, struct list_head *); - void (*lm_setup)(struct file_lock *, void **); -+ bool (*lm_breaker_owns_lease)(struct file_lock *); - }; - - struct lock_manager { -diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h -index 1afe38eb33f7e..ab6e12d9fcf61 100644 ---- a/include/linux/sunrpc/svc.h -+++ b/include/linux/sunrpc/svc.h -@@ -299,6 +299,7 @@ struct svc_rqst { - struct net *rq_bc_net; /* pointer to backchannel's - * net namespace - */ -+ void ** rq_lease_breaker; /* The v4 client breaking a lease */ - }; - - #define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net) --- -2.25.1 - diff --git a/queue-5.4/nfsd4-fix-nfsdfs-reference-count-loop.patch b/queue-5.4/nfsd4-fix-nfsdfs-reference-count-loop.patch index 62b6bb5cca2..75a52f75065 100644 --- a/queue-5.4/nfsd4-fix-nfsdfs-reference-count-loop.patch +++ b/queue-5.4/nfsd4-fix-nfsdfs-reference-count-loop.patch @@ -1,4 +1,4 @@ -From 848447bfd70b752f41e622c3bd211e657c662f01 Mon Sep 17 00:00:00 2001 +From 6618d203bf463695e6feb39671df726e3817209e Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 23 Jun 2020 16:00:33 -0400 Subject: nfsd4: fix nfsdfs reference count loop @@ -23,10 +23,10 @@ Signed-off-by: Sasha Levin 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 1e8f5e281bb53..fa3dcaa82572e 100644 +index c107caa565254..bdfae3ba39539 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c -@@ -7719,9 +7719,14 @@ nfs4_state_start_net(struct net *net) +@@ -7859,9 +7859,14 @@ nfs4_state_start_net(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int ret; @@ -42,7 +42,7 @@ index 1e8f5e281bb53..fa3dcaa82572e 100644 locks_start_grace(net, &nn->nfsd4_manager); nfsd4_client_tracking_init(net); if (nn->track_reclaim_completes && nn->reclaim_str_hashtbl_size == 0) -@@ -7790,6 +7795,7 @@ nfs4_state_shutdown_net(struct net *net) +@@ -7930,6 +7935,7 @@ nfs4_state_shutdown_net(struct net *net) nfsd4_client_tracking_exit(net); nfs4_state_destroy_net(net); @@ -51,7 +51,7 @@ index 1e8f5e281bb53..fa3dcaa82572e 100644 void diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c -index 159feae6af8ba..596ed6a42022d 100644 +index 71687d99b0901..9b22d857549c3 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1424,6 +1424,18 @@ static struct file_system_type nfsd_fs_type = { @@ -73,7 +73,7 @@ index 159feae6af8ba..596ed6a42022d 100644 #ifdef CONFIG_PROC_FS static int create_proc_exports_entry(void) { -@@ -1452,7 +1464,6 @@ unsigned int nfsd_net_id; +@@ -1451,7 +1463,6 @@ unsigned int nfsd_net_id; static __net_init int nfsd_init_net(struct net *net) { int retval; @@ -81,7 +81,7 @@ index 159feae6af8ba..596ed6a42022d 100644 struct nfsd_net *nn = net_generic(net, nfsd_net_id); retval = nfsd_export_init(net); -@@ -1479,16 +1490,8 @@ static __net_init int nfsd_init_net(struct net *net) +@@ -1478,16 +1489,8 @@ static __net_init int nfsd_init_net(struct net *net) init_waitqueue_head(&nn->ntf_wq); seqlock_init(&nn->boot_lock); @@ -98,7 +98,7 @@ index 159feae6af8ba..596ed6a42022d 100644 out_drc_error: nfsd_idmap_shutdown(net); out_idmap_error: -@@ -1501,7 +1504,6 @@ static __net_exit void nfsd_exit_net(struct net *net) +@@ -1500,7 +1503,6 @@ static __net_exit void nfsd_exit_net(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); @@ -107,19 +107,19 @@ index 159feae6af8ba..596ed6a42022d 100644 nfsd_idmap_shutdown(net); nfsd_export_shutdown(net); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index 7a835fb7d79f7..65097324b42a0 100644 +index 2ab5569126b8a..b61de3cd69b72 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h -@@ -89,6 +89,8 @@ void nfsd_destroy(struct net *net); +@@ -88,6 +88,8 @@ int nfsd_pool_stats_release(struct inode *, struct file *); - bool i_am_nfsd(void); + void nfsd_destroy(struct net *net); +int get_nfsdfs(struct net *); + struct nfsdfs_client { struct kref cl_ref; void (*cl_release)(struct kref *kref); -@@ -99,6 +101,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, +@@ -98,6 +100,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, struct nfsdfs_client *ncl, u32 id, const struct tree_descr *); void nfsd_client_rmdir(struct dentry *dentry); diff --git a/queue-5.4/series b/queue-5.4/series index f874f6dc6c8..3a41254e519 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -31,8 +31,6 @@ hwmon-max6697-make-sure-the-overt-mask-is-set-correc.patch hwmon-acpi_power_meter-fix-potential-memory-leak-in-.patch thermal-drivers-mediatek-fix-bank-number-settings-on.patch thermal-drivers-rcar_gen3-fix-undefined-temperature-.patch -kthread-save-thread-function.patch -nfsd-clients-don-t-need-to-break-their-own-delegatio.patch nfsd4-fix-nfsdfs-reference-count-loop.patch nfsd-fix-nfsdfs-inode-reference-count-leak.patch drm-sun4i-hdmi-remove-extra-hpd-polling.patch diff --git a/queue-5.7/kthread-save-thread-function.patch b/queue-5.7/kthread-save-thread-function.patch deleted file mode 100644 index e3f2bc57d9d..00000000000 --- a/queue-5.7/kthread-save-thread-function.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 88f3389631349cc31df367bf898616fa8c3ea728 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 6 May 2020 12:09:34 -0400 -Subject: kthread: save thread function - -From: J. Bruce Fields - -[ Upstream commit 52782c92ac85c4e393eb4a903a62e6c24afa633f ] - -It's handy to keep the kthread_fn just as a unique cookie to identify -classes of kthreads. E.g. if you can verify that a given task is -running your thread_fn, then you may know what sort of type kthread_data -points to. - -We'll use this in nfsd to pass some information into the vfs. Note it -will need kthread_data() exported too. - -Original-patch-by: Tejun Heo -Signed-off-by: J. Bruce Fields -Signed-off-by: Sasha Levin ---- - include/linux/kthread.h | 1 + - kernel/kthread.c | 17 +++++++++++++++++ - 2 files changed, 18 insertions(+) - -diff --git a/include/linux/kthread.h b/include/linux/kthread.h -index 8bbcaad7ef0f4..c2a274b79c429 100644 ---- a/include/linux/kthread.h -+++ b/include/linux/kthread.h -@@ -57,6 +57,7 @@ bool kthread_should_stop(void); - bool kthread_should_park(void); - bool __kthread_should_park(struct task_struct *k); - bool kthread_freezable_should_stop(bool *was_frozen); -+void *kthread_func(struct task_struct *k); - void *kthread_data(struct task_struct *k); - void *kthread_probe_data(struct task_struct *k); - int kthread_park(struct task_struct *k); -diff --git a/kernel/kthread.c b/kernel/kthread.c -index bfbfa481be3a5..b84fc7eec0358 100644 ---- a/kernel/kthread.c -+++ b/kernel/kthread.c -@@ -46,6 +46,7 @@ struct kthread_create_info - struct kthread { - unsigned long flags; - unsigned int cpu; -+ int (*threadfn)(void *); - void *data; - struct completion parked; - struct completion exited; -@@ -152,6 +153,20 @@ bool kthread_freezable_should_stop(bool *was_frozen) - } - EXPORT_SYMBOL_GPL(kthread_freezable_should_stop); - -+/** -+ * kthread_func - return the function specified on kthread creation -+ * @task: kthread task in question -+ * -+ * Returns NULL if the task is not a kthread. -+ */ -+void *kthread_func(struct task_struct *task) -+{ -+ if (task->flags & PF_KTHREAD) -+ return to_kthread(task)->threadfn; -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(kthread_func); -+ - /** - * kthread_data - return data value specified on kthread creation - * @task: kthread task in question -@@ -164,6 +179,7 @@ void *kthread_data(struct task_struct *task) - { - return to_kthread(task)->data; - } -+EXPORT_SYMBOL_GPL(kthread_data); - - /** - * kthread_probe_data - speculative version of kthread_data() -@@ -244,6 +260,7 @@ static int kthread(void *_create) - do_exit(-ENOMEM); - } - -+ self->threadfn = threadfn; - self->data = data; - init_completion(&self->exited); - init_completion(&self->parked); --- -2.25.1 - diff --git a/queue-5.7/nfsd-clients-don-t-need-to-break-their-own-delegatio.patch b/queue-5.7/nfsd-clients-don-t-need-to-break-their-own-delegatio.patch deleted file mode 100644 index 2f119d24df6..00000000000 --- a/queue-5.7/nfsd-clients-don-t-need-to-break-their-own-delegatio.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 14afb49cf00c95d3a499e1919f4b946b676783af Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 28 Jul 2017 16:35:15 -0400 -Subject: nfsd: clients don't need to break their own delegations - -From: J. Bruce Fields - -[ Upstream commit 28df3d1539de5090f7916f6fff03891b67f366f4 ] - -We currently revoke read delegations on any write open or any operation -that modifies file data or metadata (including rename, link, and -unlink). But if the delegation in question is the only read delegation -and is held by the client performing the operation, that's not really -necessary. - -It's not always possible to prevent this in the NFSv4.0 case, because -there's not always a way to determine which client an NFSv4.0 delegation -came from. (In theory we could try to guess this from the transport -layer, e.g., by assuming all traffic on a given TCP connection comes -from the same client. But that's not really correct.) - -In the NFSv4.1 case the session layer always tells us the client. - -This patch should remove such self-conflicts in all cases where we can -reliably determine the client from the compound. - -To do that we need to track "who" is performing a given (possibly -lease-breaking) file operation. We're doing that by storing the -information in the svc_rqst and using kthread_data() to map the current -task back to a svc_rqst. - -Signed-off-by: J. Bruce Fields -Signed-off-by: Sasha Levin ---- - Documentation/filesystems/locking.rst | 2 ++ - fs/locks.c | 3 +++ - fs/nfsd/nfs4proc.c | 2 ++ - fs/nfsd/nfs4state.c | 14 ++++++++++++++ - fs/nfsd/nfsd.h | 2 ++ - fs/nfsd/nfssvc.c | 6 ++++++ - include/linux/fs.h | 1 + - include/linux/sunrpc/svc.h | 1 + - 8 files changed, 31 insertions(+) - -diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst -index 5057e4d9dcd1d..9fdcec4166142 100644 ---- a/Documentation/filesystems/locking.rst -+++ b/Documentation/filesystems/locking.rst -@@ -425,6 +425,7 @@ prototypes:: - int (*lm_grant)(struct file_lock *, struct file_lock *, int); - void (*lm_break)(struct file_lock *); /* break_lease callback */ - int (*lm_change)(struct file_lock **, int); -+ bool (*lm_breaker_owns_lease)(struct file_lock *); - - locking rules: - -@@ -435,6 +436,7 @@ lm_notify: yes yes no - lm_grant: no no no - lm_break: yes no no - lm_change yes no no -+lm_breaker_owns_lease: no no no - ========== ============= ================= ========= - - buffer_head -diff --git a/fs/locks.c b/fs/locks.c -index b8a31c1c4fff3..a3f186846e93e 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -1557,6 +1557,9 @@ static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker) - { - bool rc; - -+ if (lease->fl_lmops->lm_breaker_owns_lease -+ && lease->fl_lmops->lm_breaker_owns_lease(lease)) -+ return false; - if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT)) { - rc = false; - goto trace; -diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c -index 0e75f7fb5fec0..a6d73aa51ce4e 100644 ---- a/fs/nfsd/nfs4proc.c -+++ b/fs/nfsd/nfs4proc.c -@@ -2302,6 +2302,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) - } - check_if_stalefh_allowed(args); - -+ rqstp->rq_lease_breaker = (void **)&cstate->clp; -+ - trace_nfsd_compound(rqstp, args->opcnt); - while (!status && resp->opcnt < args->opcnt) { - op = &args->ops[resp->opcnt++]; -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index c107caa565254..f71e5590967bb 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -4522,6 +4522,19 @@ nfsd_break_deleg_cb(struct file_lock *fl) - return ret; - } - -+static bool nfsd_breaker_owns_lease(struct file_lock *fl) -+{ -+ struct nfs4_delegation *dl = fl->fl_owner; -+ struct svc_rqst *rqst; -+ struct nfs4_client *clp; -+ -+ if (!i_am_nfsd()) -+ return NULL; -+ rqst = kthread_data(current); -+ clp = *(rqst->rq_lease_breaker); -+ return dl->dl_stid.sc_client == clp; -+} -+ - static int - nfsd_change_deleg_cb(struct file_lock *onlist, int arg, - struct list_head *dispose) -@@ -4533,6 +4546,7 @@ nfsd_change_deleg_cb(struct file_lock *onlist, int arg, - } - - static const struct lock_manager_operations nfsd_lease_mng_ops = { -+ .lm_breaker_owns_lease = nfsd_breaker_owns_lease, - .lm_break = nfsd_break_deleg_cb, - .lm_change = nfsd_change_deleg_cb, - }; -diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index 2ab5569126b8a..36cdd81b6688a 100644 ---- a/fs/nfsd/nfsd.h -+++ b/fs/nfsd/nfsd.h -@@ -88,6 +88,8 @@ int nfsd_pool_stats_release(struct inode *, struct file *); - - void nfsd_destroy(struct net *net); - -+bool i_am_nfsd(void); -+ - struct nfsdfs_client { - struct kref cl_ref; - void (*cl_release)(struct kref *kref); -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index ca9fd348548b8..4f588c0eaaf44 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -601,6 +601,11 @@ static const struct svc_serv_ops nfsd_thread_sv_ops = { - .svo_module = THIS_MODULE, - }; - -+bool i_am_nfsd() -+{ -+ return kthread_func(current) == nfsd; -+} -+ - int nfsd_create_serv(struct net *net) - { - int error; -@@ -1011,6 +1016,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - *statp = rpc_garbage_args; - return 1; - } -+ rqstp->rq_lease_breaker = NULL; - /* - * Give the xdr decoder a chance to change this if it wants - * (necessary in the NFSv4.0 compound case) -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 45cc10cdf6ddd..70a0ac7b8f66a 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1045,6 +1045,7 @@ struct lock_manager_operations { - bool (*lm_break)(struct file_lock *); - int (*lm_change)(struct file_lock *, int, struct list_head *); - void (*lm_setup)(struct file_lock *, void **); -+ bool (*lm_breaker_owns_lease)(struct file_lock *); - }; - - struct lock_manager { -diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h -index fd390894a5849..abf4a57ce4a7d 100644 ---- a/include/linux/sunrpc/svc.h -+++ b/include/linux/sunrpc/svc.h -@@ -299,6 +299,7 @@ struct svc_rqst { - struct net *rq_bc_net; /* pointer to backchannel's - * net namespace - */ -+ void ** rq_lease_breaker; /* The v4 client breaking a lease */ - }; - - #define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net) --- -2.25.1 - diff --git a/queue-5.7/nfsd4-fix-nfsdfs-reference-count-loop.patch b/queue-5.7/nfsd4-fix-nfsdfs-reference-count-loop.patch index f3755ea3902..75a52f75065 100644 --- a/queue-5.7/nfsd4-fix-nfsdfs-reference-count-loop.patch +++ b/queue-5.7/nfsd4-fix-nfsdfs-reference-count-loop.patch @@ -1,4 +1,4 @@ -From b706c5495fc492b4d72fece8d8f78a5e2102a8a4 Mon Sep 17 00:00:00 2001 +From 6618d203bf463695e6feb39671df726e3817209e Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 23 Jun 2020 16:00:33 -0400 Subject: nfsd4: fix nfsdfs reference count loop @@ -23,10 +23,10 @@ Signed-off-by: Sasha Levin 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index f71e5590967bb..95e459a1dd7dc 100644 +index c107caa565254..bdfae3ba39539 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c -@@ -7873,9 +7873,14 @@ nfs4_state_start_net(struct net *net) +@@ -7859,9 +7859,14 @@ nfs4_state_start_net(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int ret; @@ -42,7 +42,7 @@ index f71e5590967bb..95e459a1dd7dc 100644 locks_start_grace(net, &nn->nfsd4_manager); nfsd4_client_tracking_init(net); if (nn->track_reclaim_completes && nn->reclaim_str_hashtbl_size == 0) -@@ -7944,6 +7949,7 @@ nfs4_state_shutdown_net(struct net *net) +@@ -7930,6 +7935,7 @@ nfs4_state_shutdown_net(struct net *net) nfsd4_client_tracking_exit(net); nfs4_state_destroy_net(net); @@ -107,19 +107,19 @@ index 71687d99b0901..9b22d857549c3 100644 nfsd_idmap_shutdown(net); nfsd_export_shutdown(net); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index 36cdd81b6688a..57c832d1b30fd 100644 +index 2ab5569126b8a..b61de3cd69b72 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h -@@ -90,6 +90,8 @@ void nfsd_destroy(struct net *net); +@@ -88,6 +88,8 @@ int nfsd_pool_stats_release(struct inode *, struct file *); - bool i_am_nfsd(void); + void nfsd_destroy(struct net *net); +int get_nfsdfs(struct net *); + struct nfsdfs_client { struct kref cl_ref; void (*cl_release)(struct kref *kref); -@@ -100,6 +102,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, +@@ -98,6 +100,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, struct nfsdfs_client *ncl, u32 id, const struct tree_descr *); void nfsd_client_rmdir(struct dentry *dentry); diff --git a/queue-5.7/series b/queue-5.7/series index fd9e47ebab4..8adbe1c0006 100644 --- a/queue-5.7/series +++ b/queue-5.7/series @@ -67,8 +67,6 @@ scsi-qla2xxx-fix-a-condition-in-qla2x00_find_all_fab.patch thermal-drivers-mediatek-fix-bank-number-settings-on.patch thermal-drivers-sprd-fix-return-value-of-sprd_thm_pr.patch thermal-drivers-rcar_gen3-fix-undefined-temperature-.patch -kthread-save-thread-function.patch -nfsd-clients-don-t-need-to-break-their-own-delegatio.patch nfsd4-fix-nfsdfs-reference-count-loop.patch nfsd-fix-nfsdfs-inode-reference-count-leak.patch drm-sun4i-hdmi-remove-extra-hpd-polling.patch