aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c14
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);
879out: 881out:
880 return err; 882 return err;
881} 883}