Commit e80bdc5e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfsd-5.16-2' of git://linux-nfs.org/~bfields/linux

Pull nfsd fixes from Bruce Fields:
 "Fix a race on startup and another in the delegation code.

  The latter has been around for years, but I suspect recent changes may
  have widened the race window a little, so I'd like to go ahead and get
  it in"

* tag 'nfsd-5.16-2' of git://linux-nfs.org/~bfields/linux:
  nfsd: fix use-after-free due to delegation race
  nfsd: Fix nsfd startup race (again)
parents b9902641 548ec080
...@@ -2156,6 +2156,7 @@ static struct notifier_block nfsd4_cld_block = { ...@@ -2156,6 +2156,7 @@ static struct notifier_block nfsd4_cld_block = {
int int
register_cld_notifier(void) register_cld_notifier(void)
{ {
WARN_ON(!nfsd_net_id);
return rpc_pipefs_notifier_register(&nfsd4_cld_block); return rpc_pipefs_notifier_register(&nfsd4_cld_block);
} }
......
...@@ -1207,6 +1207,11 @@ hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp) ...@@ -1207,6 +1207,11 @@ hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
return 0; return 0;
} }
static bool delegation_hashed(struct nfs4_delegation *dp)
{
return !(list_empty(&dp->dl_perfile));
}
static bool static bool
unhash_delegation_locked(struct nfs4_delegation *dp) unhash_delegation_locked(struct nfs4_delegation *dp)
{ {
...@@ -1214,7 +1219,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp) ...@@ -1214,7 +1219,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp)
lockdep_assert_held(&state_lock); lockdep_assert_held(&state_lock);
if (list_empty(&dp->dl_perfile)) if (!delegation_hashed(dp))
return false; return false;
dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID; dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
...@@ -4598,7 +4603,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb) ...@@ -4598,7 +4603,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
* queued for a lease break. Don't queue it again. * queued for a lease break. Don't queue it again.
*/ */
spin_lock(&state_lock); spin_lock(&state_lock);
if (dp->dl_time == 0) { if (delegation_hashed(dp) && dp->dl_time == 0) {
dp->dl_time = ktime_get_boottime_seconds(); dp->dl_time = ktime_get_boottime_seconds();
list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
} }
......
...@@ -1521,12 +1521,9 @@ static int __init init_nfsd(void) ...@@ -1521,12 +1521,9 @@ static int __init init_nfsd(void)
int retval; int retval;
printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
retval = register_cld_notifier();
if (retval)
return retval;
retval = nfsd4_init_slabs(); retval = nfsd4_init_slabs();
if (retval) if (retval)
goto out_unregister_notifier; return retval;
retval = nfsd4_init_pnfs(); retval = nfsd4_init_pnfs();
if (retval) if (retval)
goto out_free_slabs; goto out_free_slabs;
...@@ -1545,9 +1542,14 @@ static int __init init_nfsd(void) ...@@ -1545,9 +1542,14 @@ static int __init init_nfsd(void)
goto out_free_exports; goto out_free_exports;
retval = register_pernet_subsys(&nfsd_net_ops); retval = register_pernet_subsys(&nfsd_net_ops);
if (retval < 0) if (retval < 0)
goto out_free_filesystem;
retval = register_cld_notifier();
if (retval)
goto out_free_all; goto out_free_all;
return 0; return 0;
out_free_all: out_free_all:
unregister_pernet_subsys(&nfsd_net_ops);
out_free_filesystem:
unregister_filesystem(&nfsd_fs_type); unregister_filesystem(&nfsd_fs_type);
out_free_exports: out_free_exports:
remove_proc_entry("fs/nfs/exports", NULL); remove_proc_entry("fs/nfs/exports", NULL);
...@@ -1561,13 +1563,12 @@ static int __init init_nfsd(void) ...@@ -1561,13 +1563,12 @@ static int __init init_nfsd(void)
nfsd4_exit_pnfs(); nfsd4_exit_pnfs();
out_free_slabs: out_free_slabs:
nfsd4_free_slabs(); nfsd4_free_slabs();
out_unregister_notifier:
unregister_cld_notifier();
return retval; return retval;
} }
static void __exit exit_nfsd(void) static void __exit exit_nfsd(void)
{ {
unregister_cld_notifier();
unregister_pernet_subsys(&nfsd_net_ops); unregister_pernet_subsys(&nfsd_net_ops);
nfsd_drc_slab_free(); nfsd_drc_slab_free();
remove_proc_entry("fs/nfs/exports", NULL); remove_proc_entry("fs/nfs/exports", NULL);
...@@ -1577,7 +1578,6 @@ static void __exit exit_nfsd(void) ...@@ -1577,7 +1578,6 @@ static void __exit exit_nfsd(void)
nfsd4_free_slabs(); nfsd4_free_slabs();
nfsd4_exit_pnfs(); nfsd4_exit_pnfs();
unregister_filesystem(&nfsd_fs_type); unregister_filesystem(&nfsd_fs_type);
unregister_cld_notifier();
} }
MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment