summaryrefslogtreecommitdiffstats
path: root/fs/smbfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/smbfs')
-rw-r--r--fs/smbfs/sock.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c
index f14836199..45a0790fc 100644
--- a/fs/smbfs/sock.c
+++ b/fs/smbfs/sock.c
@@ -26,8 +26,6 @@
#define SMBFS_PARANOIA 1
/* #define SMBFS_DEBUG_VERBOSE 1 */
-#define _S(nr) (1<<((nr)-1))
-
static int
_recvfrom(struct socket *socket, unsigned char *ubuf, int size,
unsigned flags)
@@ -89,7 +87,7 @@ smb_data_callback(struct sock *sk, int len)
struct socket *socket = sk->socket;
unsigned char peek_buf[4];
int result;
- unsigned long fs;
+ mm_segment_t fs;
fs = get_fs();
set_fs(get_ds());
@@ -324,7 +322,7 @@ smb_get_length(struct socket *socket, unsigned char *header)
{
int result;
unsigned char peek_buf[4];
- unsigned long fs;
+ mm_segment_t fs;
re_recv:
fs = get_fs();
@@ -599,8 +597,9 @@ out_error:
int
smb_request(struct smb_sb_info *server)
{
- unsigned long old_mask;
- unsigned long fs;
+ unsigned long flags, sigpipe;
+ mm_segment_t fs;
+ sigset_t old_set;
int len, result;
unsigned char *buffer;
@@ -619,8 +618,13 @@ smb_request(struct smb_sb_info *server)
len = smb_len(buffer) + 4;
pr_debug("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
- old_mask = current->blocked;
- current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ sigpipe = sigismember(&current->signal, SIGPIPE);
+ old_set = current->blocked;
+ siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
fs = get_fs();
set_fs(get_ds());
@@ -629,9 +633,15 @@ smb_request(struct smb_sb_info *server)
{
result = smb_receive(server);
}
+
/* read/write errors are handled by errno */
- current->signal &= ~_S(SIGPIPE);
- current->blocked = old_mask;
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ if (result == -EPIPE && !sigpipe)
+ sigdelset(&current->signal, SIGPIPE);
+ current->blocked = old_set;
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
set_fs(fs);
if (result >= 0)
@@ -758,8 +768,9 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
int *lrdata, unsigned char **rdata,
int *lrparam, unsigned char **rparam)
{
- unsigned long old_mask;
- unsigned long fs;
+ sigset_t old_set;
+ unsigned long flags, sigpipe;
+ mm_segment_t fs;
int result;
pr_debug("smb_trans2_request: com=%d, ld=%d, lp=%d\n",
@@ -778,8 +789,13 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
if ((result = smb_dont_catch_keepalive(server)) != 0)
goto bad_conn;
- old_mask = current->blocked;
- current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ sigpipe = sigismember(&current->signal, SIGPIPE);
+ old_set = current->blocked;
+ siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
fs = get_fs();
set_fs(get_ds());
@@ -790,9 +806,15 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
result = smb_receive_trans2(server,
lrdata, rdata, lrparam, rparam);
}
+
/* read/write errors are handled by errno */
- current->signal &= ~_S(SIGPIPE);
- current->blocked = old_mask;
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ if (result == -EPIPE && !sigpipe)
+ sigdelset(&current->signal, SIGPIPE);
+ current->blocked = old_set;
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
set_fs(fs);
if (result >= 0)