root/fs/smbfs/sock.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smb_data_callback
  2. smb_catch_keepalive
  3. smb_dont_catch_keepalive
  4. smb_receive_raw
  5. smb_receive
  6. smb_receive_trans2
  7. server_sock
  8. smb_release
  9. smb_connect
  10. smb_request
  11. smb_trans2_request
  12. smb_request_read_raw
  13. smb_request_write_raw

   1 /*
   2  *  sock.c
   3  *
   4  *  Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
   5  *
   6  */
   7 
   8 #include <linux/config.h>
   9 #ifdef MODULE
  10 #include <linux/module.h>
  11 #include <linux/version.h>
  12 #endif
  13 
  14 #include <linux/sched.h>
  15 #include <linux/smb_fs.h>
  16 #include <linux/errno.h>
  17 #include <linux/socket.h>
  18 #include <linux/fcntl.h>
  19 #include <linux/stat.h>
  20 #include <asm/segment.h>
  21 #include <linux/in.h>
  22 #include <linux/net.h>
  23 #include <linux/mm.h>
  24 #include <linux/netdevice.h>
  25 #include <net/ip.h>
  26 
  27 #include <linux/smb.h>
  28 #include <linux/smbno.h>
  29 
  30 
  31 #define _S(nr) (1<<((nr)-1))
  32 
  33 static void
  34 smb_data_callback(struct sock *sk,int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36         struct socket *sock = sk->socket;
  37 
  38         if(!sk->dead)
  39         {
  40                 unsigned char peek_buf[4];
  41                 int result;
  42                 unsigned short fs;
  43 
  44                 fs = get_fs();
  45                 set_fs(get_ds());
  46 
  47                 result = sock->ops->recvfrom(sock, (void *)peek_buf, 1, 1,
  48                                              MSG_PEEK, NULL, NULL);
  49 
  50                 while ((result != -EAGAIN) && (peek_buf[0] == 0x85)) {
  51 
  52                         /* got SESSION KEEP ALIVE */
  53                         result = sock->ops->recvfrom(sock, (void *)peek_buf,
  54                                                      4, 1, 0, NULL, NULL);
  55 
  56                         DDPRINTK("smb_data_callback:"
  57                                  " got SESSION KEEP ALIVE\n");
  58 
  59                         if (result == -EAGAIN)
  60                                 break;
  61 
  62                         result = sock->ops->recvfrom(sock, (void *)peek_buf,
  63                                                      1, 1, MSG_PEEK,
  64                                                      NULL, NULL);
  65 
  66                 }
  67 
  68                 set_fs(fs);
  69 
  70                 if (result != -EAGAIN) {
  71                         wake_up_interruptible(sk->sleep);
  72                 }
  73         }
  74 }
  75 
  76 int
  77 smb_catch_keepalive(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         struct file   *file;
  80         struct inode  *inode;
  81         struct socket *sock;
  82         struct sock   *sk;
  83 
  84         if (   (server == NULL)
  85             || ((file  = server->sock_file) == NULL)
  86             || ((inode = file->f_inode) == NULL)
  87             || (!S_ISSOCK(inode->i_mode))) {
  88 
  89                 printk("smb_catch_keepalive: did not get valid server!\n");
  90                 server->data_ready = NULL;
  91                 return -EINVAL;
  92         }
  93 
  94         sock = &(inode->u.socket_i);
  95 
  96         if (sock->type != SOCK_STREAM) {
  97                 printk("smb_catch_keepalive: did not get SOCK_STREAM\n");
  98                 server->data_ready = NULL;
  99                 return -EINVAL;
 100         }
 101 
 102         sk   = (struct sock *)(sock->data);
 103 
 104         if (sk == NULL) {
 105                 printk("smb_catch_keepalive: sk == NULL");
 106                 server->data_ready = NULL;
 107                 return -EINVAL;
 108         }
 109 
 110         DDPRINTK("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
 111                  (unsigned int)(sk->data_ready),
 112                  (unsigned int)(server->data_ready));
 113 
 114         if (sk->data_ready == smb_data_callback) {
 115                 printk("smb_catch_keepalive: already done\n");
 116                 return -EINVAL;
 117         }
 118 
 119         server->data_ready = sk->data_ready;
 120         sk->data_ready = smb_data_callback;
 121         return 0;
 122 }
 123                 
 124 int
 125 smb_dont_catch_keepalive(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 126 {
 127         struct file   *file;
 128         struct inode  *inode;
 129         struct socket *sock;
 130         struct sock   *sk;
 131 
 132         if (   (server == NULL)
 133             || ((file  = server->sock_file) == NULL)
 134             || ((inode = file->f_inode) == NULL)
 135             || (!S_ISSOCK(inode->i_mode))) {
 136 
 137                 printk("smb_dont_catch_keepalive: "
 138                        "did not get valid server!\n");
 139                 return -EINVAL;
 140         }
 141 
 142         sock = &(inode->u.socket_i);
 143 
 144         if (sock->type != SOCK_STREAM) {
 145                 printk("smb_dont_catch_keepalive: did not get SOCK_STREAM\n");
 146                 return -EINVAL;
 147         }
 148 
 149         sk   = (struct sock *)(sock->data);
 150 
 151         if (sk == NULL) {
 152                 printk("smb_dont_catch_keepalive: sk == NULL");
 153                 return -EINVAL;
 154         }
 155 
 156         if (server->data_ready == NULL) {
 157                 printk("smb_dont_catch_keepalive: "
 158                        "server->data_ready == NULL\n");
 159                 return -EINVAL;
 160         }
 161 
 162         if (sk->data_ready != smb_data_callback) {
 163                 printk("smb_dont_catch_keepalive: "
 164                        "sk->data_callback != smb_data_callback\n");
 165                 return -EINVAL;
 166         }
 167 
 168         DDPRINTK("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
 169                  (unsigned int)(sk->data_ready),
 170                  (unsigned int)(server->data_ready));
 171 
 172         sk->data_ready = server->data_ready;
 173         server->data_ready = NULL;
 174         return 0;
 175 }
 176 
 177 /*
 178  * smb_receive_raw
 179  * fs points to the correct segment, sock != NULL, target != NULL
 180  * The smb header is only stored if want_header != 0.
 181  */
 182 static int
 183 smb_receive_raw(struct socket *sock, unsigned char *target,
     /* [previous][next][first][last][top][bottom][index][help] */
 184                 int max_raw_length, int want_header)
 185 {
 186         int len, result;
 187         int already_read;
 188         unsigned char peek_buf[4];
 189         unsigned short fs;      /* We fool the kernel to believe
 190                                    we call from user space. */
 191 
 192 
 193  re_recv:
 194 
 195         fs = get_fs();
 196         set_fs(get_ds());
 197         result = sock->ops->recvfrom(sock, (void *)peek_buf, 4, 0,
 198                                      0, NULL, NULL);
 199         set_fs(fs);
 200 
 201         if (result < 0) {
 202                 DPRINTK("smb_receive_raw: recv error = %d\n", -result);
 203                 return result;
 204         }
 205 
 206         if (result < 4) {
 207                 DPRINTK("smb_receive_raw: got less than 4 bytes\n");
 208                 return -EIO;
 209         }
 210 
 211         switch (peek_buf[0]) {
 212 
 213         case 0x00:
 214         case 0x82:
 215                 break;
 216 
 217         case 0x85:
 218                 DPRINTK("smb_receive_raw: Got SESSION KEEP ALIVE\n");
 219                 goto re_recv;
 220                 
 221         default:
 222                 printk("smb_receive_raw: Invalid packet\n");
 223                 return -EIO;
 224         }
 225 
 226         /* The length in the RFC NB header is the raw data length */
 227         len = smb_len(peek_buf); 
 228         if (len > max_raw_length) { 
 229                 printk("smb_receive_raw: Received length (%d) > max_xmit (%d)!\n", 
 230                        len, max_raw_length);
 231                 return -EIO;
 232         }
 233 
 234         if (want_header != 0) {
 235                 memcpy_tofs(target, peek_buf, 4);
 236                 target += 4;
 237         }
 238 
 239         already_read = 0;
 240 
 241         while (already_read < len) {
 242                 
 243                 result = sock->ops->
 244                         recvfrom(sock,
 245                                  (void *)(target+already_read),
 246                                  len - already_read, 0, 0,
 247                                  NULL, NULL);
 248    
 249                 if (result < 0) {
 250                         printk("smb_receive_raw: recvfrom error = %d\n",
 251                                -result);
 252                         return result;
 253                 }
 254 
 255                 already_read += result;
 256         }
 257         return already_read;
 258 }
 259 
 260 /*
 261  * smb_receive
 262  * fs points to the correct segment, server != NULL, sock!=NULL
 263  */
 264 static int
 265 smb_receive(struct smb_server *server, struct socket *sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267         int result;
 268 
 269         result = smb_receive_raw(sock, server->packet,
 270                                  server->max_xmit - 4, /* max_xmit in server
 271                                                           includes NB header */
 272                                  1); /* We want the header */
 273 
 274         if (result < 0) {
 275                 printk("smb_receive: receive error: %d\n", result);
 276                 return result;
 277         }
 278 
 279         server->rcls = *((unsigned char *)(server->packet+9));
 280         server->err  = *((unsigned short *)(server->packet+11));
 281 
 282         if (server->rcls != 0) {
 283                 DPRINTK("smb_receive: rcls=%d, err=%d\n",
 284                         server->rcls, server->err);
 285         }
 286 
 287         return result;
 288 }
 289 
 290 
 291 /*
 292  * smb_receive's preconditions also apply here.
 293  */
 294 static int
 295 smb_receive_trans2(struct smb_server *server, struct socket *sock,
     /* [previous][next][first][last][top][bottom][index][help] */
 296                    int *data_len, int *param_len,
 297                    char **data, char **param)
 298 {
 299         int total_data=0;
 300         int total_param=0;
 301         int result;
 302         unsigned char *inbuf = server->packet;
 303 
 304         *data_len = *param_len = 0;
 305 
 306         DDPRINTK("smb_receive_trans2: enter\n");
 307         
 308         if ((result = smb_receive(server, sock)) < 0) {
 309                 return result;
 310         }
 311 
 312         if (server->rcls != 0) {
 313                 return result;
 314         }
 315 
 316         /* parse out the lengths */
 317         total_data = WVAL(inbuf,smb_tdrcnt);
 318         total_param = WVAL(inbuf,smb_tprcnt);
 319 
 320         if (   (total_data  > TRANS2_MAX_TRANSFER)
 321             || (total_param > TRANS2_MAX_TRANSFER)) {
 322                 printk("smb_receive_trans2: data/param too long\n");
 323                 return -EIO;
 324         }
 325 
 326         /* allocate it */
 327         if ((*data  = smb_kmalloc(total_data, GFP_KERNEL)) == NULL) {
 328                 printk("smb_receive_trans2: could not alloc data area\n");
 329                 return -ENOMEM;
 330         }
 331 
 332         if ((*param = smb_kmalloc(total_param, GFP_KERNEL)) == NULL) {
 333                 printk("smb_receive_trans2: could not alloc param area\n");
 334                 smb_kfree_s(*data, total_data);
 335                 return -ENOMEM;
 336         }
 337 
 338         DDPRINTK("smb_rec_trans2: total_data/param: %d/%d\n",
 339                  total_data, total_param);
 340 
 341         while (1)
 342         {
 343                 if (WVAL(inbuf,smb_prdisp)+WVAL(inbuf, smb_prcnt)
 344                     > total_param) {
 345                         printk("smb_receive_trans2: invalid parameters\n");
 346                         result = -EIO;
 347                         goto fail;
 348                 }
 349                 memcpy(*param + WVAL(inbuf,smb_prdisp),
 350                        smb_base(inbuf) + WVAL(inbuf,smb_proff),
 351                        WVAL(inbuf,smb_prcnt));
 352                 *param_len += WVAL(inbuf,smb_prcnt);
 353 
 354 
 355                 if (WVAL(inbuf,smb_drdisp)+WVAL(inbuf, smb_drcnt)>total_data) {
 356                         printk("smb_receive_trans2: invalid data block\n");
 357                         result = -EIO;
 358                         goto fail;
 359                 }
 360                 memcpy(*data + WVAL(inbuf,smb_drdisp),
 361                        smb_base(inbuf) + WVAL(inbuf,smb_droff),
 362                        WVAL(inbuf,smb_drcnt));
 363                 *data_len += WVAL(inbuf,smb_drcnt);
 364 
 365                 DDPRINTK("smb_rec_trans2: drcnt/prcnt: %d/%d\n",
 366                          WVAL(inbuf, smb_drcnt), WVAL(inbuf, smb_prcnt));
 367 
 368                 /* parse out the total lengths again - they can shrink! */
 369 
 370                 if (   (WVAL(inbuf,smb_tdrcnt) > total_data)
 371                     || (WVAL(inbuf,smb_tprcnt) > total_param)) {
 372                         printk("smb_receive_trans2: data/params grew!\n");
 373                         result = -EIO;
 374                         goto fail;
 375                 }
 376 
 377                 total_data = WVAL(inbuf,smb_tdrcnt);
 378                 total_param = WVAL(inbuf,smb_tprcnt);
 379 
 380                 if (total_data <= *data_len && total_param <= *param_len)
 381                         break;
 382 
 383                 if ((result = smb_receive(server, sock)) < 0) {
 384                         goto fail;
 385                 }
 386                 if (server->rcls != 0) {
 387                         result = -EIO;
 388                         goto fail;
 389                 }
 390         }
 391 
 392         DDPRINTK("smb_receive_trans2: normal exit\n");
 393 
 394         return 0;
 395 
 396  fail:
 397         DPRINTK("smb_receive_trans2: failed exit\n");
 398 
 399         smb_kfree_s(*param, 0); *param = NULL;
 400         smb_kfree_s(*data, 0);  *data = NULL;
 401         return result;
 402 }
 403 
 404 static inline struct socket *
 405 server_sock(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 406 {
 407         struct file *file;
 408         struct inode *inode;
 409 
 410         if (server == NULL)
 411                 return NULL;
 412         if ((file = server->sock_file) == NULL)
 413                 return NULL;
 414         if ((inode = file->f_inode) == NULL)
 415                 return NULL;
 416         return &(inode->u.socket_i);
 417 }
 418 
 419 int
 420 smb_release(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 421 {
 422         struct socket *sock = server_sock(server);
 423         int result;
 424 
 425         if (sock == NULL)
 426                 return -EINVAL;
 427 
 428         result = sock->ops->release(sock, NULL);
 429         DPRINTK("smb_release: sock->ops->release = %d\n", result);
 430 
 431         /* inet_release does not set sock->state.  Maybe someone is
 432            confused about sock->state being SS_CONNECTED while there
 433            is nothing behind it, so I set it to SS_UNCONNECTED.*/
 434         sock->state = SS_UNCONNECTED;
 435 
 436         result = sock->ops->create(sock, 0);
 437         DPRINTK("smb_release: sock->ops->create = %d\n", result);
 438         return result;
 439 }
 440 
 441 int
 442 smb_connect(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 443 {
 444         struct socket *sock = server_sock(server);
 445         if (sock == NULL)
 446                 return -EINVAL;
 447         if (sock->state != SS_UNCONNECTED) {
 448                 DPRINTK("smb_connect: socket is not unconnected: %d\n",
 449                         sock->state);
 450         }
 451         return sock->ops->connect(sock, (struct sockaddr *)&(server->m.addr),
 452                                   sizeof(struct sockaddr_in), 0);
 453 }
 454         
 455 /*****************************************************************************/
 456 /*                                                                           */
 457 /*  This routine was once taken from nfs, wich is for udp. Here TCP does     */
 458 /*  most of the ugly stuff for us (thanks, Alan!)                            */
 459 /*                                                                           */
 460 /*****************************************************************************/
 461 int
 462 smb_request(struct smb_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 463 {
 464         unsigned long old_mask;
 465         unsigned short fs;      /* We fool the kernel to believe
 466                                    we call from user space. */
 467         int len, result, result2;
 468 
 469         struct socket *sock = server_sock(server);
 470         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 471 
 472         if ((sock == NULL) || (buffer == NULL)) {
 473                 printk("smb_request: Bad server!\n");
 474                 return -EBADF;
 475         }
 476 
 477         if (server->state != CONN_VALID)
 478                 return -EIO;
 479                 
 480         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 481                 server->state = CONN_INVALID;
 482                 smb_invalidate_all_inodes(server);
 483                 return result;
 484         }
 485 
 486         len = smb_len(buffer) + 4;
 487 
 488         DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
 489 
 490         old_mask = current->blocked;
 491         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 492         fs = get_fs();
 493         set_fs(get_ds());
 494 
 495         result = sock->ops->send(sock, (void *)buffer, len, 0, 0);
 496         if (result < 0) {
 497                 printk("smb_request: send error = %d\n", result);
 498         }
 499         else {
 500                 result = smb_receive(server, sock);
 501         }
 502 
 503         /* read/write errors are handled by errno */
 504         current->signal &= ~_S(SIGPIPE);
 505 
 506         current->blocked = old_mask;
 507         set_fs(fs);
 508 
 509         if ((result2 = smb_catch_keepalive(server)) < 0) {
 510                 result = result2;
 511         }
 512 
 513         if (result < 0) {
 514                 server->state = CONN_INVALID;
 515                 smb_invalidate_all_inodes(server);
 516         }
 517         
 518         DDPRINTK("smb_request: result = %d\n", result);
 519 
 520         return result;
 521 }
 522 
 523 /*
 524  * This is not really a trans2 request, we assume that you only have
 525  * one packet to send.
 526  */ 
 527 int
 528 smb_trans2_request(struct smb_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 529                    int *data_len, int *param_len,
 530                    char **data, char **param)
 531 {
 532         unsigned long old_mask;
 533         unsigned short fs;      /* We fool the kernel to believe
 534                                    we call from user space. */
 535         int len, result, result2;
 536 
 537         struct socket *sock = server_sock(server);
 538         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 539 
 540         if ((sock == NULL) || (buffer == NULL)) {
 541                 printk("smb_trans2_request: Bad server!\n");
 542                 return -EBADF;
 543         }
 544 
 545         if (server->state != CONN_VALID)
 546                 return -EIO;
 547                 
 548         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 549                 server->state = CONN_INVALID;
 550                 smb_invalidate_all_inodes(server);
 551                 return result;
 552         }
 553 
 554         len = smb_len(buffer) + 4;
 555 
 556         old_mask = current->blocked;
 557         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 558         fs = get_fs();
 559         set_fs(get_ds());
 560 
 561         DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
 562 
 563         result = sock->ops->send(sock, (void *)buffer, len, 0, 0);
 564         if (result < 0) {
 565                 printk("smb_trans2_request: send error = %d\n", result);
 566         }
 567         else {
 568                 result = smb_receive_trans2(server, sock,
 569                                             data_len, param_len,
 570                                             data, param);
 571         }
 572 
 573         /* read/write errors are handled by errno */
 574         current->signal &= ~_S(SIGPIPE);
 575 
 576         current->blocked = old_mask;
 577         set_fs(fs);
 578 
 579         if ((result2 = smb_catch_keepalive(server)) < 0) {
 580                 result = result2;
 581         }
 582 
 583         if (result < 0) {
 584                 server->state = CONN_INVALID;
 585                 smb_invalidate_all_inodes(server);
 586         }
 587         
 588         DDPRINTK("smb_trans2_request: result = %d\n", result);
 589 
 590         return result;
 591 }
 592 
 593 /* target must be in user space */
 594 int
 595 smb_request_read_raw(struct smb_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 596                      unsigned char *target, int max_len)
 597 {
 598         unsigned long old_mask;
 599         int len, result, result2;
 600         unsigned short fs;      /* We fool the kernel to believe
 601                                    we call from user space. */
 602 
 603         struct socket *sock = server_sock(server);
 604         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 605 
 606         if ((sock == NULL) || (buffer == NULL)) {
 607                 printk("smb_request_read_raw: Bad server!\n");
 608                 return -EBADF;
 609         }
 610 
 611         if (server->state != CONN_VALID)
 612                 return -EIO;
 613                 
 614         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 615                 server->state = CONN_INVALID;
 616                 smb_invalidate_all_inodes(server);
 617                 return result;
 618         }
 619 
 620         len = smb_len(buffer) + 4;
 621 
 622         old_mask = current->blocked;
 623         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 624         fs = get_fs();
 625         set_fs(get_ds());
 626 
 627         DPRINTK("smb_request_read_raw: len = %d cmd = 0x%X\n",
 628                 len, buffer[8]);
 629         DPRINTK("smb_request_read_raw: target=%X, max_len=%d\n",
 630                 (unsigned int)target, max_len);
 631         DPRINTK("smb_request_read_raw: buffer=%X, sock=%X\n",
 632                 (unsigned int)buffer, (unsigned int)sock);
 633 
 634         result = sock->ops->send(sock, (void *)buffer, len, 0, 0);
 635 
 636         DPRINTK("smb_request_read_raw: send returned %d\n", result);
 637 
 638         set_fs(fs);             /* We recv into user space */
 639 
 640         if (result < 0) {
 641                 printk("smb_request_read_raw: send error = %d\n", result);
 642         }
 643         else {
 644                 result = smb_receive_raw(sock, target, max_len, 0);
 645         }
 646 
 647         /* read/write errors are handled by errno */
 648         current->signal &= ~_S(SIGPIPE);
 649         current->blocked = old_mask;
 650 
 651         if ((result2 = smb_catch_keepalive(server)) < 0) {
 652                 result = result2;
 653         }
 654 
 655         if (result < 0) {
 656                 server->state = CONN_INVALID;
 657                 smb_invalidate_all_inodes(server);
 658         }
 659         
 660         DPRINTK("smb_request_read_raw: result = %d\n", result);
 661 
 662         return result;
 663 }
 664 
 665 /* Source must be in user space. smb_request_write_raw assumes that
 666  * the request SMBwriteBraw has been completed successfully, so that
 667  * we can send the raw data now.  */
 668 int
 669 smb_request_write_raw(struct smb_server *server,
     /* [previous][next][first][last][top][bottom][index][help] */
 670                       unsigned const char *source, int length)
 671 {
 672         unsigned long old_mask;
 673         int result, result2;
 674         unsigned short fs;      /* We fool the kernel to believe
 675                                    we call from user space. */
 676         byte nb_header[4];
 677 
 678         struct socket *sock = server_sock(server);
 679         unsigned char *buffer = (server == NULL) ? NULL : server->packet;
 680 
 681         if ((sock == NULL) || (buffer == NULL)) {
 682                 printk("smb_request_write_raw: Bad server!\n");
 683                 return -EBADF;
 684         }
 685 
 686         if (server->state != CONN_VALID)
 687                 return -EIO;
 688                 
 689         if ((result = smb_dont_catch_keepalive(server)) != 0) {
 690                 server->state = CONN_INVALID;
 691                 smb_invalidate_all_inodes(server);
 692                 return result;
 693         }
 694 
 695         old_mask = current->blocked;
 696         current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP));
 697         fs = get_fs();
 698         set_fs(get_ds());
 699 
 700         smb_encode_smb_length(nb_header, length);
 701 
 702         result = sock->ops->send(sock, (void *)nb_header, 4, 0, 0);
 703 
 704         if (result == 4) {
 705                 set_fs(fs);     /* source is in user-land */
 706                 result = sock->ops->send(sock, (void *)source, length, 0, 0);
 707                 set_fs(get_ds());
 708         } else {
 709                 result = -EIO;
 710         }
 711 
 712         DPRINTK("smb_request_write_raw: send returned %d\n", result);
 713 
 714         if (result == length) {
 715                 result = smb_receive(server, sock);
 716         } else {
 717                 result = -EIO;
 718         }
 719 
 720         /* read/write errors are handled by errno */
 721         current->signal &= ~_S(SIGPIPE);
 722         current->blocked = old_mask;
 723         set_fs(fs);
 724 
 725         if ((result2 = smb_catch_keepalive(server)) < 0) {
 726                 result = result2;
 727         }
 728 
 729         if (result < 0) {
 730                 server->state = CONN_INVALID;
 731                 smb_invalidate_all_inodes(server);
 732         }
 733 
 734         if (result > 0) {
 735                 result = length;
 736         }
 737         
 738         DPRINTK("smb_request_write_raw: result = %d\n", result);
 739 
 740         return result;
 741 }
 742 
 743 /*
 744  * Overrides for Emacs so that we follow Linus's tabbing style.
 745  * Emacs will notice this stuff at the end of the file and automatically
 746  * adjust the settings for this buffer only.  This must remain at the end
 747  * of the file.
 748  * ---------------------------------------------------------------------------
 749  * Local variables:
 750  * c-indent-level: 8
 751  * c-brace-imaginary-offset: 0
 752  * c-brace-offset: -8
 753  * c-argdecl-indent: 8
 754  * c-label-offset: -8
 755  * c-continued-statement-offset: 8
 756  * c-continued-brace-offset: 0
 757  * End:
 758  */

/* [previous][next][first][last][top][bottom][index][help] */