summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs
diff options
context:
space:
mode:
authorPetr Vandrovec <petr@vandrovec.name>2010-09-29 14:39:11 +0200
committerArnd Bergmann <arnd@arndb.de>2010-10-05 11:02:14 +0200
commit2a4df5d33202e99c015928bf2a2dfd8ad03e53bc (patch)
tree3825ceca1afac81dbfe676b4fff9672ce2278d1b /fs/ncpfs
parentb89f432133851a01c0d28822f11cbdcc15781a75 (diff)
downloadlinux-2a4df5d33202e99c015928bf2a2dfd8ad03e53bc.tar.gz
linux-2a4df5d33202e99c015928bf2a2dfd8ad03e53bc.tar.bz2
linux-2a4df5d33202e99c015928bf2a2dfd8ad03e53bc.zip
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/ncpfs')
-rw-r--r--fs/ncpfs/inode.c14
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)
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);