patch-2.3.48 linux/fs/smbfs/sock.c
Next file: linux/fs/super.c
Previous file: linux/fs/smbfs/inode.c
Back to the patch index
Back to the overall index
- Lines: 123
- Date:
Sat Feb 26 08:17:28 2000
- Orig file:
v2.3.47/linux/fs/smbfs/sock.c
- Orig date:
Sat Feb 28 13:29:35 1998
diff -u --recursive --new-file v2.3.47/linux/fs/smbfs/sock.c linux/fs/smbfs/sock.c
@@ -15,6 +15,7 @@
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
+#include <linux/smp_lock.h>
#include <net/scm.h>
#include <net/ip.h>
@@ -79,13 +80,33 @@
return err;
}
+struct data_callback {
+ struct tq_struct cb;
+ struct sock *sk;
+};
/*
* N.B. What happens if we're in here when the socket closes??
*/
static void
-smb_data_callback(struct sock *sk, int len)
+found_data(struct sock *sk)
{
- struct socket *socket = sk->socket;
+ /*
+ * FIXME: copied from sock_def_readable, it should be a call to
+ * server->data_ready() -- manfreds@colorfullife.com
+ */
+ read_lock(&sk->callback_lock);
+ if(!sk->dead) {
+ wake_up_interruptible(sk->sleep);
+ sock_wake_async(sk->socket,1,POLL_IN);
+ }
+ read_unlock(&sk->callback_lock);
+}
+
+static void
+smb_data_callback(void* ptr)
+{
+ struct data_callback* job=ptr;
+ struct socket *socket = job->sk->socket;
unsigned char peek_buf[4];
int result;
mm_segment_t fs;
@@ -93,10 +114,11 @@
fs = get_fs();
set_fs(get_ds());
+ lock_kernel();
while (1)
{
result = -EIO;
- if (sk->dead)
+ if (job->sk->dead)
{
#ifdef SMBFS_PARANOIA
printk("smb_data_callback: sock dead!\n");
@@ -120,12 +142,30 @@
if (result == -EAGAIN)
break;
}
+ unlock_kernel();
set_fs(fs);
if (result != -EAGAIN)
- {
- wake_up_interruptible(sk->sleep);
+ found_data(job->sk);
+ kfree(ptr);
+}
+
+static void
+smb_data_ready(struct sock *sk, int len)
+{
+ struct data_callback* job;
+ job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
+ if(job == 0) {
+ printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+ found_data(sk);
+ return;
}
+ job->cb.next = NULL;
+ job->cb.sync = 0;
+ job->cb.routine = smb_data_callback;
+ job->cb.data = job;
+ job->sk = sk;
+ queue_task(&job->cb, &tq_scheduler);
}
int
@@ -182,8 +222,8 @@
/*
* Install the callback atomically to avoid races ...
*/
- data_ready = xchg(&sk->data_ready, smb_data_callback);
- if (data_ready != smb_data_callback)
+ data_ready = xchg(&sk->data_ready, smb_data_ready);
+ if (data_ready != smb_data_ready)
{
server->data_ready = data_ready;
error = 0;
@@ -232,10 +272,10 @@
*/
data_ready = xchg(&sk->data_ready, server->data_ready);
server->data_ready = NULL;
- if (data_ready != smb_data_callback)
+ if (data_ready != smb_data_ready)
{
printk("smb_dont_catch_keepalive: "
- "sk->data_callback != smb_data_callback\n");
+ "sk->data_ready != smb_data_ready\n");
}
error = 0;
out:
@@ -256,7 +296,7 @@
printk("smb_close_socket: closing socket %p\n", server_sock(server));
#endif
#ifdef SMBFS_PARANOIA
-if (server_sock(server)->sk->data_ready == smb_data_callback)
+if (server_sock(server)->sk->data_ready == smb_data_ready)
printk("smb_close_socket: still catching keepalives!\n");
#endif
server->sock_file = NULL;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)