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