diff options
Diffstat (limited to 'drivers/net/tun.c')
| -rw-r--r-- | drivers/net/tun.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a4fdad475594..fed298c0cb39 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -856,10 +856,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file, | |||
| 856 | err = 0; | 856 | err = 0; |
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | rcu_assign_pointer(tfile->tun, tun); | ||
| 860 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | ||
| 861 | tun->numqueues++; | ||
| 862 | |||
| 863 | if (tfile->detached) { | 859 | if (tfile->detached) { |
| 864 | tun_enable_queue(tfile); | 860 | tun_enable_queue(tfile); |
| 865 | } else { | 861 | } else { |
| @@ -870,12 +866,18 @@ static int tun_attach(struct tun_struct *tun, struct file *file, | |||
| 870 | if (rtnl_dereference(tun->xdp_prog)) | 866 | if (rtnl_dereference(tun->xdp_prog)) |
| 871 | sock_set_flag(&tfile->sk, SOCK_XDP); | 867 | sock_set_flag(&tfile->sk, SOCK_XDP); |
| 872 | 868 | ||
| 873 | tun_set_real_num_queues(tun); | ||
| 874 | |||
| 875 | /* device is allowed to go away first, so no need to hold extra | 869 | /* device is allowed to go away first, so no need to hold extra |
| 876 | * refcnt. | 870 | * refcnt. |
| 877 | */ | 871 | */ |
| 878 | 872 | ||
| 873 | /* Publish tfile->tun and tun->tfiles only after we've fully | ||
| 874 | * initialized tfile; otherwise we risk using half-initialized | ||
| 875 | * object. | ||
| 876 | */ | ||
| 877 | rcu_assign_pointer(tfile->tun, tun); | ||
| 878 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | ||
| 879 | tun->numqueues++; | ||
| 880 | tun_set_real_num_queues(tun); | ||
| 879 | out: | 881 | out: |
| 880 | return err; | 882 | return err; |
| 881 | } | 883 | } |
