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