patch-2.4.20 linux-2.4.20/fs/smbfs/sock.c
Next file: linux-2.4.20/fs/super.c
Previous file: linux-2.4.20/fs/smbfs/smb_debug.h
Back to the patch index
Back to the overall index
- Lines: 126
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/fs/smbfs/sock.c
- Orig date:
Tue Oct 2 17:03:34 2001
diff -urN linux-2.4.19/fs/smbfs/sock.c linux-2.4.20/fs/smbfs/sock.c
@@ -12,6 +12,7 @@
#include <linux/socket.h>
#include <linux/fcntl.h>
#include <linux/file.h>
+#include <linux/poll.h>
#include <linux/in.h>
#include <linux/net.h>
#include <linux/mm.h>
@@ -305,6 +306,55 @@
}
}
+/*
+ * Poll the server->socket to allow receives to time out.
+ * returns 0 when ok to continue, <0 on errors.
+ */
+static int
+smb_receive_poll(struct smb_sb_info *server)
+{
+ struct file *file = server->sock_file;
+ poll_table wait_table;
+ int result = 0;
+ int timeout = server->mnt->timeo * HZ;
+ int mask;
+
+ for (;;) {
+ poll_initwait(&wait_table);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ mask = file->f_op->poll(file, &wait_table);
+ if (mask & POLLIN) {
+ poll_freewait(&wait_table);
+ current->state = TASK_RUNNING;
+ break;
+ }
+
+ timeout = schedule_timeout(timeout);
+ poll_freewait(&wait_table);
+ set_current_state(TASK_RUNNING);
+
+ if (wait_table.error) {
+ result = wait_table.error;
+ break;
+ }
+
+ if (signal_pending(current)) {
+ /* we got a signal (which?) tell the caller to
+ try again (on all signals?). */
+ DEBUG1("got signal_pending()\n");
+ result = -ERESTARTSYS;
+ break;
+ }
+ if (!timeout) {
+ printk(KERN_WARNING "SMB server not responding\n");
+ result = -EIO;
+ break;
+ }
+ }
+ return result;
+}
+
static int
smb_send_raw(struct socket *socket, unsigned char *source, int length)
{
@@ -332,13 +382,19 @@
}
static int
-smb_receive_raw(struct socket *socket, unsigned char *target, int length)
+smb_receive_raw(struct smb_sb_info *server, unsigned char *target, int length)
{
int result;
int already_read = 0;
+ struct socket *socket = server_sock(server);
while (already_read < length)
{
+ result = smb_receive_poll(server);
+ if (result < 0) {
+ DEBUG1("poll error = %d\n", -result);
+ return result;
+ }
result = _recvfrom(socket,
(void *) (target + already_read),
length - already_read, 0);
@@ -358,7 +414,7 @@
}
static int
-smb_get_length(struct socket *socket, unsigned char *header)
+smb_get_length(struct smb_sb_info *server, unsigned char *header)
{
int result;
unsigned char peek_buf[4];
@@ -367,7 +423,7 @@
re_recv:
fs = get_fs();
set_fs(get_ds());
- result = smb_receive_raw(socket, peek_buf, 4);
+ result = smb_receive_raw(server, peek_buf, 4);
set_fs(fs);
if (result < 0)
@@ -415,12 +471,11 @@
static int
smb_receive(struct smb_sb_info *server)
{
- struct socket *socket = server_sock(server);
unsigned char * packet = server->packet;
int len, result;
unsigned char peek_buf[4];
- result = smb_get_length(socket, peek_buf);
+ result = smb_get_length(server, peek_buf);
if (result < 0)
goto out;
len = result;
@@ -442,7 +497,7 @@
server->packet_size = new_len;
}
memcpy(packet, peek_buf, 4);
- result = smb_receive_raw(socket, packet + 4, len);
+ result = smb_receive_raw(server, packet + 4, len);
if (result < 0)
{
VERBOSE("receive error: %d\n", result);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)