ncpfs: Lock socket in ncpfs while setting its callbacks
authorPetr Vandrovec <petr@vandrovec.name>
Wed, 29 Sep 2010 12:39:11 +0000 (14:39 +0200)
committerArnd Bergmann <arnd@arndb.de>
Tue, 5 Oct 2010 09:02:14 +0000 (11:02 +0200)
Otherwise partially updated pointers could be seen if
pointer update is not atomic.

Signed-off-by: Petr Vandrovec <petr@vandrovec.name>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
fs/ncpfs/inode.c

index 5f4e58d93fdd908f3ffe4a95e71966e1ddad2a1e..985fabb26aca44edcacc889af0a8d2c5c47e8f04 100644 (file)
@@ -303,10 +303,12 @@ ncp_evict_inode(struct inode *inode)
 
 static void ncp_stop_tasks(struct ncp_server *server) {
        struct sock* sk = server->ncp_sock->sk;
-               
+
+       lock_sock(sk);
        sk->sk_error_report = server->error_report;
        sk->sk_data_ready   = server->data_ready;
        sk->sk_write_space  = server->write_space;
+       release_sock(sk);
        del_timer_sync(&server->timeout_tm);
        flush_scheduled_work();
 }
@@ -605,10 +607,6 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        mutex_init(&server->rcv.creq_mutex);
        server->tx.creq         = NULL;
        server->rcv.creq        = NULL;
-       server->data_ready      = sock->sk->sk_data_ready;
-       server->write_space     = sock->sk->sk_write_space;
-       server->error_report    = sock->sk->sk_error_report;
-       sock->sk->sk_user_data  = server;
 
        init_timer(&server->timeout_tm);
 #undef NCP_PACKET_SIZE
@@ -625,6 +623,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        if (server->rxbuf == NULL)
                goto out_txbuf;
 
+       lock_sock(sock->sk);
+       server->data_ready      = sock->sk->sk_data_ready;
+       server->write_space     = sock->sk->sk_write_space;
+       server->error_report    = sock->sk->sk_error_report;
+       sock->sk->sk_user_data  = server;
        sock->sk->sk_data_ready   = ncp_tcp_data_ready;
        sock->sk->sk_error_report = ncp_tcp_error_report;
        if (sock->type == SOCK_STREAM) {
@@ -640,6 +643,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                server->timeout_tm.data = (unsigned long)server;
                server->timeout_tm.function = ncpdgram_timeout_call;
        }
+       release_sock(sock->sk);
 
        ncp_lock_server(server);
        error = ncp_connect(server);