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