This source file includes following definitions.
- do_nfs_rpc_call
 
- nfs_rpc_call
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 #include <linux/config.h>
  10 #include <linux/sched.h>
  11 #include <linux/nfs_fs.h>
  12 #include <linux/errno.h>
  13 #include <linux/socket.h>
  14 #include <linux/fcntl.h>
  15 #include <asm/segment.h>
  16 #include <linux/in.h>
  17 #include <linux/net.h>
  18 
  19 
  20 extern struct socket *socki_lookup(struct inode *inode);
  21 
  22 #define _S(nr) (1<<((nr)-1))
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end)
     
  35 {
  36         struct file *file;
  37         struct inode *inode;
  38         struct socket *sock;
  39         unsigned short fs;
  40         int result;
  41         int xid;
  42         int len;
  43         select_table wait_table;
  44         struct select_table_entry entry;
  45         int (*select) (struct inode *, struct file *, int, select_table *);
  46         int init_timeout, max_timeout;
  47         int timeout;
  48         int retrans;
  49         int major_timeout_seen;
  50         char *server_name;
  51         int n;
  52         int addrlen;
  53         unsigned long old_mask;
  54 
  55         xid = start[0];
  56         len = ((char *) end) - ((char *) start);
  57         file = server->file;
  58         inode = file->f_inode;
  59         select = file->f_op->select;
  60         sock = socki_lookup(inode);
  61         if (!sock) {
  62                 printk("nfs_rpc_call: socki_lookup failed\n");
  63                 return -EBADF;
  64         }
  65         init_timeout = server->timeo;
  66         max_timeout = NFS_MAX_RPC_TIMEOUT*HZ/10;
  67         retrans = server->retrans;
  68         major_timeout_seen = 0;
  69         server_name = server->hostname;
  70         old_mask = current->blocked;
  71         current->blocked |= ~(_S(SIGKILL)
  72 #if 0
  73                 | _S(SIGSTOP)
  74 #endif
  75                 | ((server->flags & NFS_MOUNT_INTR)
  76                 ? ((current->sigaction[SIGINT - 1].sa_handler == SIG_DFL
  77                         ? _S(SIGINT) : 0)
  78                 | (current->sigaction[SIGQUIT - 1].sa_handler == SIG_DFL
  79                         ? _S(SIGQUIT) : 0))
  80                 : 0));
  81         fs = get_fs();
  82         set_fs(get_ds());
  83         for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
  84                 result = sock->ops->send(sock, (void *) start, len, 0, 0);
  85                 if (result < 0) {
  86                         printk("nfs_rpc_call: send error = %d\n", result);
  87                         break;
  88                 }
  89         re_select:
  90                 wait_table.nr = 0;
  91                 wait_table.entry = &entry;
  92                 current->state = TASK_INTERRUPTIBLE;
  93                 if (!select(inode, file, SEL_IN, &wait_table)
  94                     && !select(inode, file, SEL_IN, NULL)) {
  95                         if (timeout > max_timeout)
  96                                 timeout = max_timeout;
  97                         current->timeout = jiffies + timeout;
  98                         schedule();
  99                         remove_wait_queue(entry.wait_address, &entry.wait);
 100                         current->state = TASK_RUNNING;
 101                         if (current->signal & ~current->blocked) {
 102                                 current->timeout = 0;
 103                                 result = -ERESTARTSYS;
 104                                 break;
 105                         }
 106                         if (!current->timeout) {
 107                                 if (n < retrans)
 108                                         continue;
 109                                 if (server->flags & NFS_MOUNT_SOFT) {
 110                                         printk("NFS server %s not responding, "
 111                                                 "timed out", server_name);
 112                                         result = -EIO;
 113                                         break;
 114                                 }
 115                                 n = 0;
 116                                 timeout = init_timeout;
 117                                 init_timeout <<= 1;
 118                                 if (!major_timeout_seen) {
 119                                         printk("NFS server %s not responding, "
 120                                                 "still trying\n", server_name);
 121                                 }
 122                                 major_timeout_seen = 1;
 123                                 continue;
 124                         }
 125                         else
 126                                 current->timeout = 0;
 127                 }
 128                 else if (wait_table.nr)
 129                         remove_wait_queue(entry.wait_address, &entry.wait);
 130                 current->state = TASK_RUNNING;
 131                 addrlen = 0;
 132                 result = sock->ops->recvfrom(sock, (void *) start, PAGE_SIZE, 1, 0,
 133                         NULL, &addrlen);
 134                 if (result < 0) {
 135                         if (result == -EAGAIN) {
 136 #if 0
 137                                 printk("nfs_rpc_call: bad select ready\n");
 138 #endif
 139                                 goto re_select;
 140                         }
 141                         if (result == -ECONNREFUSED) {
 142 #if 0
 143                                 printk("nfs_rpc_call: server playing coy\n");
 144 #endif
 145                                 goto re_select;
 146                         }
 147                         if (result != -ERESTARTSYS) {
 148                                 printk("nfs_rpc_call: recv error = %d\n",
 149                                         -result);
 150                         }
 151                         break;
 152                 }
 153                 if (*start == xid) {
 154                         if (major_timeout_seen)
 155                                 printk("NFS server %s OK\n", server_name);
 156                         break;
 157                 }
 158 #if 0
 159                 printk("nfs_rpc_call: XID mismatch\n");
 160 #endif
 161         }
 162         current->blocked = old_mask;
 163         set_fs(fs);
 164         return result;
 165 }
 166 
 167 
 168 
 169 
 170 
 171 
 172 
 173 int nfs_rpc_call(struct nfs_server *server, int *start, int *end)
     
 174 {
 175         int result;
 176 
 177         while (server->lock)
 178                 sleep_on(&server->wait);
 179         server->lock = 1;
 180         result = do_nfs_rpc_call(server, start, end);
 181         server->lock = 0;
 182         wake_up(&server->wait);
 183         return result;
 184 }
 185