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