diff options
author | Petr Vandrovec <petr@vandrovec.name> | 2010-09-29 08:39:11 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2010-10-05 05:02:14 -0400 |
commit | 2a4df5d33202e99c015928bf2a2dfd8ad03e53bc (patch) | |
tree | 3825ceca1afac81dbfe676b4fff9672ce2278d1b /fs | |
parent | b89f432133851a01c0d28822f11cbdcc15781a75 (diff) |
ncpfs: Lock socket in ncpfs while setting its callbacks
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ncpfs/inode.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 5f4e58d93fdd..985fabb26aca 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -303,10 +303,12 @@ ncp_evict_inode(struct inode *inode) | |||
303 | 303 | ||
304 | static void ncp_stop_tasks(struct ncp_server *server) { | 304 | static void ncp_stop_tasks(struct ncp_server *server) { |
305 | struct sock* sk = server->ncp_sock->sk; | 305 | struct sock* sk = server->ncp_sock->sk; |
306 | 306 | ||
307 | lock_sock(sk); | ||
307 | sk->sk_error_report = server->error_report; | 308 | sk->sk_error_report = server->error_report; |
308 | sk->sk_data_ready = server->data_ready; | 309 | sk->sk_data_ready = server->data_ready; |
309 | sk->sk_write_space = server->write_space; | 310 | sk->sk_write_space = server->write_space; |
311 | release_sock(sk); | ||
310 | del_timer_sync(&server->timeout_tm); | 312 | del_timer_sync(&server->timeout_tm); |
311 | flush_scheduled_work(); | 313 | flush_scheduled_work(); |
312 | } | 314 | } |
@@ -605,10 +607,6 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
605 | mutex_init(&server->rcv.creq_mutex); | 607 | mutex_init(&server->rcv.creq_mutex); |
606 | server->tx.creq = NULL; | 608 | server->tx.creq = NULL; |
607 | server->rcv.creq = NULL; | 609 | server->rcv.creq = NULL; |
608 | server->data_ready = sock->sk->sk_data_ready; | ||
609 | server->write_space = sock->sk->sk_write_space; | ||
610 | server->error_report = sock->sk->sk_error_report; | ||
611 | sock->sk->sk_user_data = server; | ||
612 | 610 | ||
613 | init_timer(&server->timeout_tm); | 611 | init_timer(&server->timeout_tm); |
614 | #undef NCP_PACKET_SIZE | 612 | #undef NCP_PACKET_SIZE |
@@ -625,6 +623,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
625 | if (server->rxbuf == NULL) | 623 | if (server->rxbuf == NULL) |
626 | goto out_txbuf; | 624 | goto out_txbuf; |
627 | 625 | ||
626 | lock_sock(sock->sk); | ||
627 | server->data_ready = sock->sk->sk_data_ready; | ||
628 | server->write_space = sock->sk->sk_write_space; | ||
629 | server->error_report = sock->sk->sk_error_report; | ||
630 | sock->sk->sk_user_data = server; | ||
628 | sock->sk->sk_data_ready = ncp_tcp_data_ready; | 631 | sock->sk->sk_data_ready = ncp_tcp_data_ready; |
629 | sock->sk->sk_error_report = ncp_tcp_error_report; | 632 | sock->sk->sk_error_report = ncp_tcp_error_report; |
630 | if (sock->type == SOCK_STREAM) { | 633 | if (sock->type == SOCK_STREAM) { |
@@ -640,6 +643,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
640 | server->timeout_tm.data = (unsigned long)server; | 643 | server->timeout_tm.data = (unsigned long)server; |
641 | server->timeout_tm.function = ncpdgram_timeout_call; | 644 | server->timeout_tm.function = ncpdgram_timeout_call; |
642 | } | 645 | } |
646 | release_sock(sock->sk); | ||
643 | 647 | ||
644 | ncp_lock_server(server); | 648 | ncp_lock_server(server); |
645 | error = ncp_connect(server); | 649 | error = ncp_connect(server); |