root/fs/ncpfs/sock.c

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

DEFINITIONS

This source file includes following definitions.
  1. _recvfrom
  2. _sendto
  3. ncp_wdog_data_ready
  4. ncp_catch_watchdog
  5. ncp_dont_catch_watchdog
  6. ncp_msg_data_ready
  7. ncp_catch_message
  8. do_ncp_rpc_call
  9. ncp_do_request
  10. ncp_request
  11. ncp_connect
  12. ncp_disconnect
  13. ncp_lock_server
  14. ncp_unlock_server

   1 /*
   2  *  linux/fs/ncp/sock.c
   3  *
   4  *  Copyright (C) 1992, 1993  Rick Sladkey
   5  *
   6  *  Modified 1995, 1996 by Volker Lendecke to be usable for ncp
   7  *
   8  */
   9 
  10 #include <linux/sched.h>
  11 #include <linux/ncp_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 <linux/ipx.h>
  22 
  23 #include <linux/ncp.h>
  24 #include <linux/ncp_fs.h>
  25 #include <linux/ncp_fs_sb.h>
  26 #include <net/sock.h>
  27 
  28 
  29 #define _S(nr) (1<<((nr)-1))
  30 static int _recvfrom(struct socket *sock, unsigned char *ubuf,
     /* [previous][next][first][last][top][bottom][index][help] */
  31                      int size, int noblock, unsigned flags,
  32                      struct sockaddr_ipx *sa, int *addr_len)
  33 {
  34         struct iovec iov;
  35         struct msghdr msg;
  36 
  37         iov.iov_base = ubuf;
  38         iov.iov_len  = size;
  39 
  40         msg.msg_name      = (void *)sa;
  41         msg.msg_namelen   = 0;
  42         if (addr_len)
  43                 msg.msg_namelen = *addr_len;
  44         msg.msg_accrights = NULL;
  45         msg.msg_iov       = &iov;
  46         msg.msg_iovlen    = 1;
  47 
  48         return sock->ops->recvmsg(sock, &msg, size, noblock, flags, addr_len);
  49 }
  50 
  51 static int _sendto(struct socket *sock, const void *buff,
     /* [previous][next][first][last][top][bottom][index][help] */
  52                    int len, int nonblock, unsigned flags,
  53                    struct sockaddr_ipx *sa, int addr_len)
  54 
  55 {
  56         struct iovec iov;
  57         struct msghdr msg;
  58 
  59         iov.iov_base = (void *)buff;
  60         iov.iov_len  = len;
  61 
  62         msg.msg_name      = (void *)sa;
  63         msg.msg_namelen   = addr_len;
  64         msg.msg_accrights = NULL;
  65         msg.msg_iov       = &iov;
  66         msg.msg_iovlen    = 1;
  67 
  68         return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);
  69 }
  70 
  71 
  72 static void
  73 ncp_wdog_data_ready(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75         struct socket *sock = sk->socket;
  76 
  77         if (!sk->dead)
  78         {
  79                 unsigned char packet_buf[2];
  80                 struct sockaddr_ipx sender;
  81                 int addr_len = sizeof(struct sockaddr_ipx);
  82                 int result;
  83                 unsigned short fs;
  84 
  85                 fs = get_fs();
  86                 set_fs(get_ds());
  87 
  88                 result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
  89                                    &sender, &addr_len);
  90 
  91                 if (   (result != 2)
  92                     || (packet_buf[1] != '?')
  93                     /* How to check connection number here? */
  94                     )
  95                 {
  96                         printk("ncpfs: got strange packet on watchdog "
  97                                "socket\n");
  98                 }
  99                 else
 100                 {
 101                         int result;
 102                         DDPRINTK("ncpfs: got watchdog from:\n");
 103                         DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
 104                                 " conn:%02X,type:%c\n",
 105                                 htonl(sender.sipx_network),
 106                                 sender.sipx_node[0], sender.sipx_node[1],
 107                                 sender.sipx_node[2], sender.sipx_node[3],
 108                                 sender.sipx_node[4], sender.sipx_node[5],
 109                                 ntohs(sender.sipx_port),
 110                                 packet_buf[0], packet_buf[1]);
 111 
 112                         packet_buf[1] = 'Y';
 113                         result = _sendto(sock, (void *)packet_buf, 2, 1, 0,
 114                                          &sender, sizeof(sender));
 115                         DDPRINTK("send result: %d\n", result);
 116                 }
 117                 set_fs(fs);
 118         }
 119 }
 120 
 121 int
 122 ncp_catch_watchdog(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124         struct file   *file;
 125         struct inode  *inode;
 126         struct socket *sock;
 127         struct sock   *sk;
 128 
 129         if (   (server == NULL)
 130             || ((file  = server->wdog_filp) == NULL)
 131             || ((inode = file->f_inode) == NULL)
 132             || (!S_ISSOCK(inode->i_mode)))
 133         {
 134                 printk("ncp_catch_watchdog: did not get valid server!\n");
 135                 server->data_ready = NULL;
 136                 return -EINVAL;
 137         }
 138 
 139         sock = &(inode->u.socket_i);
 140 
 141         if (sock->type != SOCK_DGRAM)
 142         {
 143                 printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n");
 144                 server->data_ready = NULL;
 145                 return -EINVAL;
 146         }
 147 
 148         sk   = (struct sock *)(sock->data);
 149 
 150         if (sk == NULL)
 151         {
 152                 printk("ncp_catch_watchdog: sk == NULL");
 153                 server->data_ready = NULL;
 154                 return -EINVAL;
 155         }
 156 
 157         DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
 158                  (unsigned int)(sk->data_ready),
 159                  (unsigned int)(server->data_ready));
 160 
 161         if (sk->data_ready == ncp_wdog_data_ready)
 162         {
 163                 printk("ncp_catch_watchdog: already done\n");
 164                 return -EINVAL;
 165         }
 166 
 167         server->data_ready = sk->data_ready;
 168         sk->data_ready = ncp_wdog_data_ready;
 169         sk->allocation = GFP_ATOMIC;
 170         return 0;
 171 }
 172                 
 173 int
 174 ncp_dont_catch_watchdog(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176         struct file   *file;
 177         struct inode  *inode;
 178         struct socket *sock;
 179         struct sock   *sk;
 180 
 181         if (   (server == NULL)
 182             || ((file  = server->wdog_filp) == NULL)
 183             || ((inode = file->f_inode) == NULL)
 184             || (!S_ISSOCK(inode->i_mode)))
 185         {
 186                 printk("ncp_dont_catch_watchdog: "
 187                        "did not get valid server!\n");
 188                 return -EINVAL;
 189         }
 190 
 191         sock = &(inode->u.socket_i);
 192 
 193         if (sock->type != SOCK_DGRAM)
 194         {
 195                 printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n");
 196                 return -EINVAL;
 197         }
 198 
 199         sk = (struct sock *)(sock->data);
 200 
 201         if (sk == NULL)
 202         {
 203                 printk("ncp_dont_catch_watchdog: sk == NULL");
 204                 return -EINVAL;
 205         }
 206 
 207         if (server->data_ready == NULL)
 208         {
 209                 printk("ncp_dont_catch_watchdog: "
 210                        "server->data_ready == NULL\n");
 211                 return -EINVAL;
 212         }
 213 
 214         if (sk->data_ready != ncp_wdog_data_ready)
 215         {
 216                 printk("ncp_dont_catch_watchdog: "
 217                        "sk->data_callback != ncp_data_callback\n");
 218                 return -EINVAL;
 219         }
 220 
 221         DDPRINTK("ncp_dont_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
 222                  (unsigned int)(sk->data_ready),
 223                  (unsigned int)(server->data_ready));
 224 
 225         sk->data_ready = server->data_ready;
 226         sk->allocation = GFP_KERNEL;
 227         server->data_ready = NULL;
 228         return 0;
 229 }
 230 
 231 static void
 232 ncp_msg_data_ready(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 233 {
 234         struct socket *sock = sk->socket;
 235 
 236         if (!sk->dead)
 237         {
 238                 unsigned char packet_buf[2];
 239                 struct sockaddr_ipx sender;
 240                 int addr_len = sizeof(struct sockaddr_ipx);
 241                 int result;
 242                 unsigned short fs;
 243 
 244                 fs = get_fs();
 245                 set_fs(get_ds());
 246 
 247                 result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
 248                                    &sender, &addr_len);
 249 
 250                 DPRINTK("ncpfs: got message of size %d from:\n", result);
 251                 DPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
 252                         " conn:%02X,type:%c\n",
 253                         htonl(sender.sipx_network),
 254                         sender.sipx_node[0], sender.sipx_node[1],
 255                         sender.sipx_node[2], sender.sipx_node[3],
 256                         sender.sipx_node[4], sender.sipx_node[5],
 257                         ntohs(sender.sipx_port),
 258                         packet_buf[0], packet_buf[1]);
 259 
 260                 ncp_trigger_message(sk->protinfo.af_ipx.ncp_server);
 261 
 262                 set_fs(fs);
 263         }
 264 }
 265 
 266 int
 267 ncp_catch_message(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 268 {
 269         struct file   *file;
 270         struct inode  *inode;
 271         struct socket *sock;
 272         struct sock   *sk;
 273 
 274         if (   (server == NULL)
 275             || ((file  = server->msg_filp) == NULL)
 276             || ((inode = file->f_inode) == NULL)
 277             || (!S_ISSOCK(inode->i_mode)))
 278         {
 279                 printk("ncp_catch_message: did not get valid server!\n");
 280                 return -EINVAL;
 281         }
 282 
 283         sock = &(inode->u.socket_i);
 284 
 285         if (sock->type != SOCK_DGRAM)
 286         {
 287                 printk("ncp_catch_message: did not get SOCK_DGRAM\n");
 288                 return -EINVAL;
 289         }
 290 
 291         sk = (struct sock *)(sock->data);
 292 
 293         if (sk == NULL)
 294         {
 295                 printk("ncp_catch_message: sk == NULL");
 296                 return -EINVAL;
 297         }
 298 
 299         DDPRINTK("ncp_catch_message: sk->d_r = %x\n",
 300                  (unsigned int)(sk->data_ready));
 301 
 302         if (sk->data_ready == ncp_msg_data_ready)
 303         {
 304                 printk("ncp_catch_message: already done\n");
 305                 return -EINVAL;
 306         }
 307 
 308         sk->data_ready = ncp_msg_data_ready;
 309         sk->protinfo.af_ipx.ncp_server = server;
 310         return 0;
 311 }
 312                 
 313 #define NCP_SLACK_SPACE 1024
 314 
 315 #define _S(nr) (1<<((nr)-1))
 316 
 317 static int
 318 do_ncp_rpc_call(struct ncp_server *server, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320         struct file *file;
 321         struct inode *inode;
 322         struct socket *sock;
 323         unsigned short fs;
 324         int result;
 325         char *start = server->packet;
 326         select_table wait_table;
 327         struct select_table_entry entry;
 328         int (*select) (struct inode *, struct file *, int, select_table *);
 329         int init_timeout, max_timeout;
 330         int timeout;
 331         int retrans;
 332         int major_timeout_seen;
 333         char *server_name;
 334         int n;
 335         int addrlen;
 336         unsigned long old_mask;
 337 
 338         /* We have to check the result, so store the complete header */
 339         struct ncp_request_header request =
 340                 *((struct ncp_request_header *)(server->packet));
 341 
 342         struct ncp_reply_header reply;  
 343 
 344 
 345         file = server->ncp_filp;
 346         inode = file->f_inode;
 347         select = file->f_op->select;
 348         sock = &inode->u.socket_i;
 349         if (!sock)
 350         {
 351                 printk("ncp_rpc_call: socki_lookup failed\n");
 352                 return -EBADF;
 353         }
 354         init_timeout = server->m.time_out;
 355         max_timeout = NCP_MAX_RPC_TIMEOUT*HZ/10;
 356         retrans = server->m.retry_count;
 357         major_timeout_seen = 0;
 358         server_name = server->m.server_name;
 359         old_mask = current->blocked;
 360         current->blocked |= ~(_S(SIGKILL)
 361 #if 0
 362                 | _S(SIGSTOP)
 363 #endif
 364                 | ((server->m.flags & NCP_MOUNT_INTR)
 365                 ? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL
 366                         ? _S(SIGINT) : 0)
 367                 | (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL
 368                         ? _S(SIGQUIT) : 0))
 369                 : 0));
 370         fs = get_fs();
 371         set_fs(get_ds());
 372         for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1)
 373         {
 374                 DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
 375                         htonl(server->m.serv_addr.sipx_network),
 376                         server->m.serv_addr.sipx_node[0],
 377                         server->m.serv_addr.sipx_node[1],
 378                         server->m.serv_addr.sipx_node[2],
 379                         server->m.serv_addr.sipx_node[3],
 380                         server->m.serv_addr.sipx_node[4],
 381                         server->m.serv_addr.sipx_node[5],
 382                         ntohs(server->m.serv_addr.sipx_port));
 383                 DDPRINTK("ncpfs: req.typ: %04X, con: %d, "
 384                         "seq: %d",
 385                         request.type,
 386                         (request.conn_high << 8) + request.conn_low,
 387                         request.sequence);
 388                 DDPRINTK(" func: %d\n",
 389                          request.function);
 390 
 391                 result = _sendto(sock, (void *) start, size, 0, 0,
 392                                  &(server->m.serv_addr),
 393                                  sizeof(server->m.serv_addr));
 394                 if (result < 0)
 395                 {
 396                         printk("ncp_rpc_call: send error = %d\n", result);
 397                         break;
 398                 }
 399         re_select:
 400                 wait_table.nr = 0;
 401                 wait_table.entry = &entry;
 402                 current->state = TASK_INTERRUPTIBLE;
 403                 if (   !select(inode, file, SEL_IN, &wait_table)
 404                     && !select(inode, file, SEL_IN, NULL))
 405                 {
 406                         if (timeout > max_timeout)
 407                         {
 408                           /* JEJB/JSP 2/7/94
 409                            * This is useful to see if the system is
 410                            * hanging */
 411                           printk("NCP max timeout reached on %s\n",
 412                                  server_name);
 413                           timeout = max_timeout;
 414                         }
 415                         current->timeout = jiffies + timeout;
 416                         schedule();
 417                         remove_wait_queue(entry.wait_address, &entry.wait);
 418                         current->state = TASK_RUNNING;
 419                         if (current->signal & ~current->blocked)
 420                         {
 421                                 current->timeout = 0;
 422                                 result = -ERESTARTSYS;
 423                                 break;
 424                         }
 425                         if (!current->timeout)
 426                         {
 427                                 if (n < retrans)
 428                                         continue;
 429                                 if (server->m.flags & NCP_MOUNT_SOFT)
 430                                 {
 431                                         printk("NCP server %s not responding, "
 432                                                 "timed out\n", server_name);
 433                                         result = -EIO;
 434                                         break;
 435                                 }
 436                                 n = 0;
 437                                 timeout = init_timeout;
 438                                 init_timeout <<= 1;
 439                                 if (!major_timeout_seen)
 440                                 {
 441                                   printk("NCP server %s not responding, "
 442                                          "still trying\n", server_name);
 443                                 }
 444                                 major_timeout_seen = 1;
 445                                 continue;
 446                         }
 447                         else
 448                                 current->timeout = 0;
 449                 }
 450                 else if (wait_table.nr)
 451                         remove_wait_queue(entry.wait_address, &entry.wait);
 452                 current->state = TASK_RUNNING;
 453                 addrlen = 0;
 454 
 455                 /* Get the header from the next packet using a peek, so keep it
 456                  * on the recv queue.  If it is wrong, it will be some reply
 457                  * we don't now need, so discard it */
 458                 result = _recvfrom(sock, (void *)&reply,
 459                                    sizeof(reply), 1, MSG_PEEK,
 460                                    NULL, &addrlen);
 461                 if (result < 0)
 462                 {
 463                         if (result == -EAGAIN)
 464                         {
 465                                 DPRINTK("ncp_rpc_call: bad select ready\n");
 466                                 goto re_select;
 467                         }
 468                         if (result == -ECONNREFUSED)
 469                         {
 470                                 DPRINTK("ncp_rpc_call: server playing coy\n");
 471                                 goto re_select;
 472                         }
 473                         if (result != -ERESTARTSYS)
 474                         {
 475                                 printk("ncp_rpc_call: recv error = %d\n",
 476                                         -result);
 477                         }
 478                         break;
 479                 }
 480                 if (   (result     == sizeof(reply))
 481                     && (reply.type == NCP_POSITIVE_ACK))
 482                 {
 483                         /* Throw away the packet */
 484                         DPRINTK("ncp_rpc_call: got positive acknowledge\n");
 485                         _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0,
 486                                   NULL, &addrlen);
 487                         goto re_select;
 488                 }
 489 
 490                 DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d,"
 491                         "seq: %d\n",
 492                         reply.type,
 493                         (reply.conn_high << 8) + reply.conn_low,
 494                         reply.task,
 495                         reply.sequence);
 496                 
 497                 if (   (result          >= sizeof(reply))
 498                     && (reply.type      == NCP_REPLY)
 499                     && (   (request.type    == NCP_ALLOC_SLOT_REQUEST)
 500                         || (   (reply.sequence  == request.sequence)
 501                             && (reply.conn_low  == request.conn_low)
 502 /* seem to get wrong task from NW311 && (reply.task      == request.task)*/
 503                             && (reply.conn_high == request.conn_high))))
 504                 {
 505                         if (major_timeout_seen)
 506                                 printk("NCP server %s OK\n", server_name);
 507                         break;
 508                 }
 509                 /* JEJB/JSP 2/7/94
 510                  * we have xid mismatch, so discard the packet and start
 511                  * again.  What a hack! but I can't call recvfrom with
 512                  * a null buffer yet. */
 513                 _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, NULL,
 514                           &addrlen);
 515 #if 1
 516                 printk("ncp_rpc_call: reply mismatch\n");
 517 #endif
 518                 goto re_select;
 519         }
 520         /* 
 521          * we have the correct reply, so read into the correct place and
 522          * return it
 523          */
 524         result = _recvfrom(sock, (void *)start, server->packet_size,
 525                            1, 0, NULL, &addrlen);
 526         if (result < 0)
 527         {
 528                 printk("NCP: notice message: result=%d\n", result);
 529         }
 530         else if (result < sizeof(struct ncp_reply_header))
 531         {
 532                 printk("NCP: just caught a too small read memory size..., "
 533                        "email to NET channel\n");
 534                 printk("NCP: result=%d,addrlen=%d\n", result, addrlen);
 535                 result = -EIO;
 536         }
 537 
 538         current->blocked = old_mask;
 539         set_fs(fs);
 540         return result;
 541 }
 542 
 543 
 544 /*
 545  * We need the server to be locked here, so check!
 546  */
 547 
 548 static int
 549 ncp_do_request(struct ncp_server *server, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 550 {
 551         int result;
 552 
 553         if (server->lock == 0)
 554         {
 555                 printk("ncpfs: Server not locked!\n");
 556                 return -EIO;
 557         }
 558 
 559         if (!ncp_conn_valid(server))
 560         {
 561                 return -EIO;
 562         }
 563 
 564         result = do_ncp_rpc_call(server, size);
 565 
 566         DDPRINTK("do_ncp_rpc_call returned %d\n", result);
 567 
 568         if (result < 0)
 569         {
 570                 /* There was a problem with I/O, so the connections is
 571                  * no longer usable. */
 572                 ncp_invalidate_conn(server);
 573         }
 574         return result;
 575 }
 576 
 577 /* ncp_do_request assures that at least a complete reply header is
 578  * received. It assumes that server->current_size contains the ncp
 579  * request size */
 580 int
 581 ncp_request(struct ncp_server *server, int function)
     /* [previous][next][first][last][top][bottom][index][help] */
 582 {
 583         struct ncp_request_header *h
 584                 = (struct ncp_request_header *)(server->packet);
 585         struct ncp_reply_header *reply
 586                 = (struct ncp_reply_header *)(server->packet);
 587 
 588         int request_size = server->current_size
 589                 - sizeof(struct ncp_request_header);
 590 
 591         int result;
 592 
 593         if (server->has_subfunction != 0)
 594         {
 595                 *(__u16 *)&(h->data[0]) = request_size - 2;
 596         }
 597 
 598         h->type = NCP_REQUEST;
 599         
 600         server->sequence += 1;
 601         h->sequence  = server->sequence;
 602         h->conn_low  = (server->connection) & 0xff;
 603         h->conn_high = ((server->connection) & 0xff00) >> 8;
 604         h->task      = (current->pid) & 0xff;
 605         h->function  = function;
 606 
 607         if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0)
 608         {
 609                 DPRINTK("ncp_request_error: %d\n", result);
 610                 return result;
 611         }
 612 
 613         server->completion  = reply->completion_code;
 614         server->conn_status = reply->connection_state;
 615         server->reply_size  = result;
 616         server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
 617 
 618         result = reply->completion_code;
 619 
 620         if (result != 0)
 621         {
 622                 DPRINTK("ncp_completion_code: %x\n", result);
 623         }
 624         return result;  
 625 }
 626 
 627 int
 628 ncp_connect(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 629 {
 630         struct ncp_request_header *h
 631                 = (struct ncp_request_header *)(server->packet);
 632         int result;
 633 
 634         h->type = NCP_ALLOC_SLOT_REQUEST;
 635         
 636         server->sequence = 0;
 637         h->sequence  = server->sequence;
 638         h->conn_low  = 0xff;
 639         h->conn_high = 0xff;
 640         h->task      = (current->pid) & 0xff;
 641         h->function  = 0;
 642 
 643         if ((result = ncp_do_request(server, sizeof(*h))) < 0)
 644         {
 645                 return result;
 646         }
 647 
 648         server->sequence = 0;
 649         server->connection = h->conn_low + (h->conn_high * 256);
 650         return 0;
 651 }
 652         
 653 int
 654 ncp_disconnect(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 655 {
 656         struct ncp_request_header *h
 657                 = (struct ncp_request_header *)(server->packet);
 658 
 659         h->type = NCP_DEALLOC_SLOT_REQUEST;
 660         
 661         server->sequence += 1;
 662         h->sequence  = server->sequence;
 663         h->conn_low  = (server->connection) & 0xff;
 664         h->conn_high = ((server->connection) & 0xff00) >> 8;
 665         h->task      = (current->pid) & 0xff;
 666         h->function  = 0;
 667 
 668         return ncp_do_request(server, sizeof(*h));
 669 }
 670 
 671 void
 672 ncp_lock_server(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 673 {
 674 #if 0
 675         /* For testing, only 1 process */
 676         if (server->lock != 0)
 677         {
 678                 DPRINTK("ncpfs: server locked!!!\n");
 679         }
 680 #endif
 681         while (server->lock)
 682                 sleep_on(&server->wait);
 683         server->lock = 1;
 684 }
 685 
 686 void
 687 ncp_unlock_server(struct ncp_server *server)
     /* [previous][next][first][last][top][bottom][index][help] */
 688 {
 689         if (server->lock != 1)
 690         {
 691                 printk("ncp_unlock_server: was not locked!\n");
 692         }
 693 
 694         server->lock = 0;
 695         wake_up(&server->wait);
 696 }
 697         

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