root/fs/nfs/nfsiod.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfsiod_reserve
  2. nfsiod_release
  3. nfsiod_enqueue
  4. nfsiod

   1 /*
   2  * linux/fs/nfs/nfsiod.c
   3  *
   4  * Async NFS RPC call support.
   5  *
   6  * When a process wants to place an asynchronous RPC call, it reserves
   7  * an nfsiod slot, fills in all necessary fields including the callback
   8  * handler field, and enqueues the request.
   9  *
  10  * This will wake up nfsiod, which calls nfs_rpc_doio to collect the
  11  * reply. It then dispatches the result to the caller via the callback
  12  * function, including result value and request pointer. It then re-inserts
  13  * itself into the free list.
  14  *
  15  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  16  */
  17 
  18 #include <linux/sched.h>
  19 #include <linux/nfs_fs.h>
  20 #include <linux/errno.h>
  21 #include <linux/rpcsock.h>
  22 #include <linux/nfsiod.h>
  23 
  24 static struct nfsiod_req *      free_list = NULL;
  25 static int                      active = 0;
  26 
  27 #undef DEBUG_NFSIOD
  28 #ifdef DEBUG_NFSIOD
  29 #define dprintk(args...)        printk(## args)
  30 #else
  31 #define dprintk(args...)        /* nothing */
  32 #endif
  33 
  34 
  35 /*
  36  * Reserve an nfsiod slot and initialize the request struct
  37  */
  38 struct nfsiod_req *
  39 nfsiod_reserve(struct nfs_server *server, nfsiod_done_fn_t callback)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         struct nfsiod_req       *req;
  42 
  43         if (!(req = free_list)) {
  44                 dprintk("BIO: nfsiod_reserve: no free nfsiods\n");
  45                 return NULL;
  46         }
  47         free_list = req->rq_next;
  48         memset(&req->rq_rpcreq, 0, sizeof(struct rpc_ioreq));
  49 
  50         if (rpc_reserve(server->rsock, &req->rq_rpcreq, 1) < 0) {
  51                 dprintk("BIO: nfsiod_reserve failed to reserve RPC slot\n");
  52                 req->rq_next = free_list;
  53                 free_list = req;
  54                 return NULL;
  55         }
  56 
  57         req->rq_server = server;
  58         req->rq_callback = callback;
  59 
  60         return req;
  61 }
  62 
  63 void
  64 nfsiod_release(struct nfsiod_req *req)
     /* [previous][next][first][last][top][bottom][index][help] */
  65 {
  66         dprintk("BIO: nfsiod_release called\n");
  67         rpc_release(req->rq_server->rsock, &req->rq_rpcreq);
  68         memset(&req->rq_rpcreq, 0, sizeof(struct rpc_ioreq));
  69         req->rq_next = free_list;
  70         free_list = req;
  71 }
  72 
  73 /*
  74  * Transmit a request and put it on nfsiod's list of pending requests.
  75  */
  76 int
  77 nfsiod_enqueue(struct nfsiod_req *req)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         int     result;
  80 
  81         dprintk("BIO: enqueuing request %p\n", &req->rq_rpcreq);
  82         result = rpc_transmit(req->rq_server->rsock, &req->rq_rpcreq);
  83         if (result < 0) {
  84                 dprintk("BIO: rpc_transmit returned %d\n", result);
  85         } else {
  86                 dprintk("BIO: waking up nfsiod (%p)\n", req->rq_wait);
  87                 wake_up(&req->rq_wait);
  88                 schedule();
  89         }
  90         return result;
  91 }
  92 
  93 /*
  94  * This is the main nfsiod loop.
  95  */
  96 int
  97 nfsiod(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         struct nfsiod_req       request, *req = &request;
 100         int                     result;
 101 
 102         dprintk("BIO: nfsiod %d starting\n", current->pid);
 103         while (1) {
 104                 /* Insert request into free list */
 105                 memset(req, 0, sizeof(*req));
 106                 req->rq_next = free_list;
 107                 free_list = req;
 108 
 109                 /* Wait until user enqueues request */
 110                 dprintk("BIO: before: now %d nfsiod's active\n", active);
 111                 dprintk("BIO: nfsiod %d waiting\n", current->pid);
 112                 interruptible_sleep_on(&req->rq_wait);
 113 
 114                 if (current->signal & ~current->blocked)
 115                         break;
 116                 if (!req->rq_rpcreq.rq_slot)
 117                         continue;
 118                 dprintk("BIO: nfsiod %d woken up; calling nfs_rpc_doio.\n",
 119                                 current->pid);
 120                 active++;
 121                 dprintk("BIO: before: now %d nfsiod's active\n", active);
 122                 result = nfs_rpc_doio(req->rq_server, &req->rq_rpcreq, 1);
 123                 req->rq_callback(result, req);
 124                 active--;
 125         }
 126 
 127         return 0;
 128 }

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