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

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