Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
67435598
Commit
67435598
authored
May 08, 2003
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux.bkbits.net/linux-2.5
into hostme.bitkeeper.com:/ua/repos/n/nfsclient/linux-2.5
parents
d498eb57
ec186a65
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
279 additions
and
157 deletions
+279
-157
fs/fs-writeback.c
fs/fs-writeback.c
+2
-1
fs/lockd/host.c
fs/lockd/host.c
+5
-9
fs/lockd/mon.c
fs/lockd/mon.c
+1
-0
fs/nfs/dir.c
fs/nfs/dir.c
+1
-1
fs/nfs/file.c
fs/nfs/file.c
+1
-1
fs/nfs/write.c
fs/nfs/write.c
+3
-3
include/linux/sunrpc/xdr.h
include/linux/sunrpc/xdr.h
+5
-0
include/linux/sunrpc/xprt.h
include/linux/sunrpc/xprt.h
+1
-1
mm/page-writeback.c
mm/page-writeback.c
+1
-1
net/sunrpc/clnt.c
net/sunrpc/clnt.c
+32
-24
net/sunrpc/sched.c
net/sunrpc/sched.c
+3
-2
net/sunrpc/xdr.c
net/sunrpc/xdr.c
+109
-2
net/sunrpc/xprt.c
net/sunrpc/xprt.c
+115
-112
No files found.
fs/fs-writeback.c
View file @
67435598
...
...
@@ -367,7 +367,8 @@ void sync_inodes_sb(struct super_block *sb, int wait)
};
get_page_state
(
&
ps
);
wbc
.
nr_to_write
=
ps
.
nr_dirty
+
ps
.
nr_dirty
/
4
;
wbc
.
nr_to_write
=
ps
.
nr_dirty
+
ps
.
nr_unstable
+
(
ps
.
nr_dirty
+
ps
.
nr_unstable
)
/
4
;
spin_lock
(
&
inode_lock
);
sync_sb_inodes
(
sb
,
&
wbc
);
spin_unlock
(
&
inode_lock
);
...
...
fs/lockd/host.c
View file @
67435598
...
...
@@ -187,15 +187,7 @@ nlm_bind_host(struct nlm_host *host)
host
->
h_nextrebind
-
jiffies
);
}
}
else
{
uid_t
saved_fsuid
=
current
->
fsuid
;
kernel_cap_t
saved_cap
=
current
->
cap_effective
;
/* Create RPC socket as root user so we get a priv port */
current
->
fsuid
=
0
;
cap_raise
(
current
->
cap_effective
,
CAP_NET_BIND_SERVICE
);
xprt
=
xprt_create_proto
(
host
->
h_proto
,
&
host
->
h_addr
,
NULL
);
current
->
fsuid
=
saved_fsuid
;
current
->
cap_effective
=
saved_cap
;
if
(
xprt
==
NULL
)
goto
forgetit
;
...
...
@@ -209,6 +201,7 @@ nlm_bind_host(struct nlm_host *host)
}
clnt
->
cl_autobind
=
1
;
/* turn on pmap queries */
xprt
->
nocong
=
1
;
/* No congestion control for NLM */
xprt
->
resvport
=
1
;
/* NLM requires a reserved port */
host
->
h_rpcclnt
=
clnt
;
}
...
...
@@ -276,7 +269,7 @@ nlm_shutdown_hosts(void)
dprintk
(
"lockd: nuking all hosts...
\n
"
);
for
(
i
=
0
;
i
<
NLM_HOST_NRHASH
;
i
++
)
{
for
(
host
=
nlm_hosts
[
i
];
host
;
host
=
host
->
h_next
)
host
->
h_expires
=
0
;
host
->
h_expires
=
jiffies
-
1
;
}
/* Then, perform a garbage collection pass */
...
...
@@ -323,6 +316,9 @@ nlm_gc_hosts(void)
while
((
host
=
*
q
)
!=
NULL
)
{
if
(
host
->
h_count
||
host
->
h_inuse
||
time_before
(
jiffies
,
host
->
h_expires
))
{
dprintk
(
"nlm_gc_hosts skipping %s (cnt %d use %d exp %ld)
\n
"
,
host
->
h_name
,
host
->
h_count
,
host
->
h_inuse
,
host
->
h_expires
);
q
=
&
host
->
h_next
;
continue
;
}
...
...
fs/lockd/mon.c
View file @
67435598
...
...
@@ -123,6 +123,7 @@ nsm_create(void)
clnt
->
cl_softrtry
=
1
;
clnt
->
cl_chatty
=
1
;
clnt
->
cl_oneshot
=
1
;
xprt
->
resvport
=
1
;
/* NSM requires a reserved port */
out:
return
clnt
;
...
...
fs/nfs/dir.c
View file @
67435598
...
...
@@ -83,7 +83,7 @@ nfs_opendir(struct inode *inode, struct file *filp)
lock_kernel
();
/* Do cto revalidation */
if
(
server
->
flags
&
NFS_MOUNT_NOCTO
)
if
(
!
(
server
->
flags
&
NFS_MOUNT_NOCTO
)
)
res
=
__nfs_revalidate_inode
(
server
,
inode
);
/* Call generic open code in order to cache credentials */
if
(
!
res
)
...
...
fs/nfs/file.c
View file @
67435598
...
...
@@ -83,7 +83,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
if
((
open
=
server
->
rpc_ops
->
file_open
)
!=
NULL
)
res
=
open
(
inode
,
filp
);
/* Do cto revalidation */
else
if
(
server
->
flags
&
NFS_MOUNT_NOCTO
)
else
if
(
!
(
server
->
flags
&
NFS_MOUNT_NOCTO
)
)
res
=
__nfs_revalidate_inode
(
server
,
inode
);
/* Call generic open code in order to cache credentials */
if
(
!
res
)
...
...
fs/nfs/write.c
View file @
67435598
...
...
@@ -280,8 +280,6 @@ nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
err
=
nfs_wb_all
(
inode
);
}
else
nfs_commit_file
(
inode
,
NULL
,
0
,
0
,
0
);
/* Avoid races. Tell upstream we've done all we were told to do */
wbc
->
nr_to_write
=
0
;
out:
return
err
;
}
...
...
@@ -490,7 +488,6 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, struct file *file, u
int
res
;
res
=
nfs_scan_list
(
&
nfsi
->
commit
,
dst
,
file
,
idx_start
,
npages
);
nfsi
->
ncommit
-=
res
;
sub_page_state
(
nr_unstable
,
res
);
if
((
nfsi
->
ncommit
==
0
)
!=
list_empty
(
&
nfsi
->
commit
))
printk
(
KERN_ERR
"NFS: desynchronized value of nfs_i.ncommit.
\n
"
);
return
res
;
...
...
@@ -1009,6 +1006,7 @@ nfs_commit_done(struct rpc_task *task)
{
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
struct
nfs_page
*
req
;
int
res
=
0
;
dprintk
(
"NFS: %4d nfs_commit_done (status %d)
\n
"
,
task
->
tk_pid
,
task
->
tk_status
);
...
...
@@ -1043,7 +1041,9 @@ nfs_commit_done(struct rpc_task *task)
nfs_mark_request_dirty
(
req
);
next:
nfs_unlock_request
(
req
);
res
++
;
}
sub_page_state
(
nr_unstable
,
res
);
}
#endif
...
...
include/linux/sunrpc/xdr.h
View file @
67435598
...
...
@@ -157,6 +157,11 @@ typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
extern
void
xdr_partial_copy_from_skb
(
struct
xdr_buf
*
,
unsigned
int
,
skb_reader_t
*
,
skb_read_actor_t
);
struct
socket
;
struct
sockaddr
;
extern
int
xdr_sendpages
(
struct
socket
*
,
struct
sockaddr
*
,
int
,
struct
xdr_buf
*
,
unsigned
int
,
int
);
/*
* Provide some simple tools for XDR buffer overflow-checking etc.
*/
...
...
include/linux/sunrpc/xprt.h
View file @
67435598
...
...
@@ -198,7 +198,7 @@ void xprt_sock_setbufsize(struct rpc_xprt *);
#define XPRT_CONNECT 0
#define xprt_connected(xp) (
!(xp)->stream ||
test_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
...
...
mm/page-writeback.c
View file @
67435598
...
...
@@ -270,7 +270,7 @@ int wakeup_bdflush(long nr_pages)
struct
page_state
ps
;
get_page_state
(
&
ps
);
nr_pages
=
ps
.
nr_dirty
;
nr_pages
=
ps
.
nr_dirty
+
ps
.
nr_unstable
;
}
return
pdflush_operation
(
background_writeout
,
nr_pages
);
}
...
...
net/sunrpc/clnt.c
View file @
67435598
...
...
@@ -57,8 +57,7 @@ static void call_refresh(struct rpc_task *task);
static
void
call_refreshresult
(
struct
rpc_task
*
task
);
static
void
call_timeout
(
struct
rpc_task
*
task
);
static
void
call_connect
(
struct
rpc_task
*
task
);
static
void
child_connect
(
struct
rpc_task
*
task
);
static
void
child_connect_status
(
struct
rpc_task
*
task
);
static
void
call_connect_status
(
struct
rpc_task
*
task
);
static
u32
*
call_header
(
struct
rpc_task
*
task
);
static
u32
*
call_verify
(
struct
rpc_task
*
task
);
...
...
@@ -602,40 +601,48 @@ static void
call_connect
(
struct
rpc_task
*
task
)
{
struct
rpc_clnt
*
clnt
=
task
->
tk_client
;
struct
rpc_task
*
child
;
dprintk
(
"RPC: %4d call_connect status %d
\n
"
,
task
->
tk_pid
,
task
->
tk_status
);
if
(
xprt_connected
(
clnt
->
cl_xprt
))
{
task
->
tk_action
=
call_transmit
;
if
(
task
->
tk_status
<
0
||
!
clnt
->
cl_xprt
->
stream
)
return
;
/* Run as a child to ensure it runs as an rpciod task. Rpciod
* guarantees we have the correct capabilities for socket bind
* to succeed. */
child
=
rpc_new_child
(
clnt
,
task
);
if
(
child
)
{
child
->
tk_action
=
child_connect
;
rpc_run_child
(
task
,
child
,
NULL
);
}
task
->
tk_action
=
call_connect_status
;
if
(
task
->
tk_status
<
0
)
return
;
xprt_connect
(
task
);
}
/*
* 4b. Sort out connect result
*/
static
void
c
hild_connect
(
struct
rpc_task
*
task
)
c
all_connect_status
(
struct
rpc_task
*
task
)
{
struct
rpc_clnt
*
clnt
=
task
->
tk_client
;
int
status
=
task
->
tk_status
;
task
->
tk_status
=
0
;
task
->
tk_action
=
child_connect_status
;
xprt_connect
(
task
);
}
if
(
status
>=
0
)
{
clnt
->
cl_stats
->
netreconn
++
;
task
->
tk_action
=
call_transmit
;
return
;
}
static
void
child_connect_status
(
struct
rpc_task
*
task
)
{
if
(
task
->
tk_status
==
-
EAGAIN
)
task
->
tk_action
=
child_connect
;
else
task
->
tk_action
=
NULL
;
/* Something failed: we may have to rebind */
if
(
clnt
->
cl_autobind
)
clnt
->
cl_port
=
0
;
switch
(
status
)
{
case
-
ENOTCONN
:
case
-
ETIMEDOUT
:
case
-
EAGAIN
:
task
->
tk_action
=
(
clnt
->
cl_port
==
0
)
?
call_bind
:
call_connect
;
break
;
default:
rpc_exit
(
task
,
-
EIO
);
}
}
/*
...
...
@@ -696,6 +703,7 @@ call_status(struct rpc_task *task)
break
;
case
-
ECONNREFUSED
:
case
-
ENOTCONN
:
req
->
rq_bytes_sent
=
0
;
if
(
clnt
->
cl_autobind
)
clnt
->
cl_port
=
0
;
task
->
tk_action
=
call_bind
;
...
...
net/sunrpc/sched.c
View file @
67435598
...
...
@@ -1110,9 +1110,10 @@ void rpc_show_tasks(void)
alltask_for_each
(
t
,
le
,
&
all_tasks
)
printk
(
"%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p
\n
"
,
t
->
tk_pid
,
(
t
->
tk_msg
.
rpc_proc
->
p_proc
?
t
->
tk_msg
.
rpc_proc
->
p_proc
:
-
1
),
(
t
->
tk_msg
.
rpc_proc
?
t
->
tk_msg
.
rpc_proc
->
p_proc
:
-
1
),
t
->
tk_flags
,
t
->
tk_status
,
t
->
tk_client
,
t
->
tk_client
->
cl_prog
,
t
->
tk_client
,
(
t
->
tk_client
?
t
->
tk_client
->
cl_prog
:
0
),
t
->
tk_rqstp
,
t
->
tk_timeout
,
rpc_qname
(
t
->
tk_rpcwait
),
t
->
tk_action
,
t
->
tk_exit
);
...
...
net/sunrpc/xdr.c
View file @
67435598
...
...
@@ -13,6 +13,8 @@
#include <linux/pagemap.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/net.h>
#include <net/sock.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>
...
...
@@ -314,8 +316,113 @@ xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
}
while
((
pglen
-=
len
)
!=
0
);
copy_tail:
len
=
xdr
->
tail
[
0
].
iov_len
;
if
(
len
)
copy_actor
(
desc
,
(
char
*
)
xdr
->
tail
[
0
].
iov_base
+
base
,
len
);
if
(
base
<
len
)
copy_actor
(
desc
,
(
char
*
)
xdr
->
tail
[
0
].
iov_base
+
base
,
len
-
base
);
}
int
xdr_sendpages
(
struct
socket
*
sock
,
struct
sockaddr
*
addr
,
int
addrlen
,
struct
xdr_buf
*
xdr
,
unsigned
int
base
,
int
msgflags
)
{
struct
page
**
ppage
=
xdr
->
pages
;
unsigned
int
len
,
pglen
=
xdr
->
page_len
;
int
err
,
ret
=
0
;
ssize_t
(
*
sendpage
)(
struct
socket
*
,
struct
page
*
,
int
,
size_t
,
int
);
mm_segment_t
oldfs
;
len
=
xdr
->
head
[
0
].
iov_len
;
if
(
base
<
len
||
(
addr
!=
NULL
&&
base
==
0
))
{
struct
iovec
iov
=
{
.
iov_base
=
xdr
->
head
[
0
].
iov_base
+
base
,
.
iov_len
=
len
-
base
,
};
struct
msghdr
msg
=
{
.
msg_name
=
addr
,
.
msg_namelen
=
addrlen
,
.
msg_flags
=
msgflags
,
};
if
(
iov
.
iov_len
!=
0
)
{
msg
.
msg_iov
=
&
iov
;
msg
.
msg_iovlen
=
1
;
}
if
(
xdr
->
len
>
len
)
msg
.
msg_flags
|=
MSG_MORE
;
oldfs
=
get_fs
();
set_fs
(
get_ds
());
err
=
sock_sendmsg
(
sock
,
&
msg
,
iov
.
iov_len
);
set_fs
(
oldfs
);
if
(
ret
==
0
)
ret
=
err
;
else
if
(
err
>
0
)
ret
+=
err
;
if
(
err
!=
iov
.
iov_len
)
goto
out
;
base
=
0
;
}
else
base
-=
len
;
if
(
pglen
==
0
)
goto
copy_tail
;
if
(
base
>=
pglen
)
{
base
-=
pglen
;
goto
copy_tail
;
}
if
(
base
||
xdr
->
page_base
)
{
pglen
-=
base
;
base
+=
xdr
->
page_base
;
ppage
+=
base
>>
PAGE_CACHE_SHIFT
;
base
&=
~
PAGE_CACHE_MASK
;
}
sendpage
=
sock
->
ops
->
sendpage
?
:
sock_no_sendpage
;
do
{
int
flags
=
msgflags
;
len
=
PAGE_CACHE_SIZE
;
if
(
base
)
len
-=
base
;
if
(
pglen
<
len
)
len
=
pglen
;
if
(
pglen
!=
len
||
xdr
->
tail
[
0
].
iov_len
!=
0
)
flags
|=
MSG_MORE
;
/* Hmm... We might be dealing with highmem pages */
if
(
PageHighMem
(
*
ppage
))
sendpage
=
sock_no_sendpage
;
err
=
sendpage
(
sock
,
*
ppage
,
base
,
len
,
flags
);
if
(
ret
==
0
)
ret
=
err
;
else
if
(
err
>
0
)
ret
+=
err
;
if
(
err
!=
len
)
goto
out
;
base
=
0
;
ppage
++
;
}
while
((
pglen
-=
len
)
!=
0
);
copy_tail:
len
=
xdr
->
tail
[
0
].
iov_len
;
if
(
base
<
len
)
{
struct
iovec
iov
=
{
.
iov_base
=
xdr
->
tail
[
0
].
iov_base
+
base
,
.
iov_len
=
len
-
base
,
};
struct
msghdr
msg
=
{
.
msg_iov
=
&
iov
,
.
msg_iovlen
=
1
,
.
msg_flags
=
msgflags
,
};
oldfs
=
get_fs
();
set_fs
(
get_ds
());
err
=
sock_sendmsg
(
sock
,
&
msg
,
iov
.
iov_len
);
set_fs
(
oldfs
);
if
(
ret
==
0
)
ret
=
err
;
else
if
(
err
>
0
)
ret
+=
err
;
}
out:
return
ret
;
}
...
...
net/sunrpc/xprt.c
View file @
67435598
...
...
@@ -85,7 +85,7 @@
static
void
xprt_request_init
(
struct
rpc_task
*
,
struct
rpc_xprt
*
);
static
inline
void
do_xprt_reserve
(
struct
rpc_task
*
);
static
void
xprt_disconnect
(
struct
rpc_xprt
*
);
static
void
xprt_conn_status
(
struct
rpc_task
*
task
);
static
void
xprt_conn
ect
_status
(
struct
rpc_task
*
task
);
static
struct
rpc_xprt
*
xprt_setup
(
int
proto
,
struct
sockaddr_in
*
ap
,
struct
rpc_timeout
*
to
);
static
struct
socket
*
xprt_create_socket
(
int
,
struct
rpc_timeout
*
,
int
);
...
...
@@ -213,11 +213,10 @@ static inline int
xprt_sendmsg
(
struct
rpc_xprt
*
xprt
,
struct
rpc_rqst
*
req
)
{
struct
socket
*
sock
=
xprt
->
sock
;
struct
msghdr
msg
;
struct
xdr_buf
*
xdr
=
&
req
->
rq_snd_buf
;
struct
iovec
niv
[
MAX_IOVEC
]
;
unsigned
int
niov
,
slen
,
skip
;
mm_segment_t
oldfs
;
struct
sockaddr
*
addr
=
NULL
;
int
addrlen
=
0
;
unsigned
int
skip
;
int
result
;
if
(
!
sock
)
...
...
@@ -227,27 +226,18 @@ xprt_sendmsg(struct rpc_xprt *xprt, struct rpc_rqst *req)
req
->
rq_svec
->
iov_base
,
req
->
rq_svec
->
iov_len
);
/* For UDP, we need to provide an address */
if
(
!
xprt
->
stream
)
{
addr
=
(
struct
sockaddr
*
)
&
xprt
->
addr
;
addrlen
=
sizeof
(
xprt
->
addr
);
}
/* Dont repeat bytes */
skip
=
req
->
rq_bytes_sent
;
slen
=
xdr
->
len
-
skip
;
niov
=
xdr_kmap
(
niv
,
xdr
,
skip
);
msg
.
msg_flags
=
MSG_DONTWAIT
|
MSG_NOSIGNAL
;
msg
.
msg_iov
=
niv
;
msg
.
msg_iovlen
=
niov
;
msg
.
msg_name
=
(
struct
sockaddr
*
)
&
xprt
->
addr
;
msg
.
msg_namelen
=
sizeof
(
xprt
->
addr
);
msg
.
msg_control
=
NULL
;
msg
.
msg_controllen
=
0
;
oldfs
=
get_fs
();
set_fs
(
get_ds
());
clear_bit
(
SOCK_ASYNC_NOSPACE
,
&
sock
->
flags
);
result
=
sock_sendmsg
(
sock
,
&
msg
,
slen
);
set_fs
(
oldfs
);
xdr_kunmap
(
xdr
,
skip
);
clear_bit
(
SOCK_ASYNC_NOSPACE
,
&
sock
->
flags
);
result
=
xdr_sendpages
(
sock
,
addr
,
addrlen
,
xdr
,
skip
,
MSG_DONTWAIT
);
dprintk
(
"RPC: xprt_sendmsg(%d) = %d
\n
"
,
slen
,
result
);
dprintk
(
"RPC: xprt_sendmsg(%d) = %d
\n
"
,
xdr
->
len
-
skip
,
result
);
if
(
result
>=
0
)
return
result
;
...
...
@@ -259,6 +249,7 @@ xprt_sendmsg(struct rpc_xprt *xprt, struct rpc_rqst *req)
*/
case
-
EAGAIN
:
break
;
case
-
ECONNRESET
:
case
-
ENOTCONN
:
case
-
EPIPE
:
/* connection broken */
...
...
@@ -376,6 +367,7 @@ xprt_close(struct rpc_xprt *xprt)
if
(
!
sk
)
return
;
write_lock_bh
(
&
sk
->
callback_lock
);
xprt
->
inet
=
NULL
;
xprt
->
sock
=
NULL
;
...
...
@@ -383,6 +375,7 @@ xprt_close(struct rpc_xprt *xprt)
sk
->
data_ready
=
xprt
->
old_data_ready
;
sk
->
state_change
=
xprt
->
old_state_change
;
sk
->
write_space
=
xprt
->
old_write_space
;
write_unlock_bh
(
&
sk
->
callback_lock
);
xprt_disconnect
(
xprt
);
sk
->
no_check
=
0
;
...
...
@@ -397,14 +390,15 @@ static void
xprt_disconnect
(
struct
rpc_xprt
*
xprt
)
{
dprintk
(
"RPC: disconnected transport %p
\n
"
,
xprt
);
spin_lock_bh
(
&
xprt
->
sock_lock
);
xprt_clear_connected
(
xprt
);
rpc_wake_up_status
(
&
xprt
->
pending
,
-
ENOTCONN
);
spin_unlock_bh
(
&
xprt
->
sock_lock
);
}
/*
* Attempt to connect a TCP socket.
*
* NB: This never collides with TCP reads, as both run from rpciod
*/
void
xprt_connect
(
struct
rpc_task
*
task
)
...
...
@@ -442,6 +436,10 @@ xprt_connect(struct rpc_task *task)
goto
out_write
;
}
xprt_bind_socket
(
xprt
,
sock
);
if
(
!
xprt
->
stream
)
goto
out_write
;
inet
=
sock
->
sk
;
/*
...
...
@@ -452,6 +450,9 @@ xprt_connect(struct rpc_task *task)
dprintk
(
"RPC: %4d connect status %d connected %d sock state %d
\n
"
,
task
->
tk_pid
,
-
status
,
xprt_connected
(
xprt
),
inet
->
state
);
if
(
status
>=
0
)
return
;
switch
(
status
)
{
case
-
EINPROGRESS
:
case
-
EALREADY
:
...
...
@@ -464,53 +465,37 @@ xprt_connect(struct rpc_task *task)
/* if the socket is already closing, delay briefly */
if
((
1
<<
inet
->
state
)
&
~
(
TCPF_SYN_SENT
|
TCPF_SYN_RECV
))
task
->
tk_timeout
=
RPC_REESTABLISH_TIMEOUT
;
rpc_sleep_on
(
&
xprt
->
pending
,
task
,
xprt_conn_status
,
rpc_sleep_on
(
&
xprt
->
pending
,
task
,
xprt_conn
ect
_status
,
NULL
);
release_sock
(
inet
);
/* task status set when task wakes up again */
return
;
}
release_sock
(
inet
);
task
->
tk_status
=
0
;
break
;
case
0
:
case
-
EISCONN
:
/* not likely, but just in case */
/* Half closed state. No race -- this socket is dead. */
if
(
inet
->
state
!=
TCP_ESTABLISHED
)
{
xprt_close
(
xprt
);
task
->
tk_status
=
-
EAGAIN
;
goto
out_write
;
}
/* Otherwise, the connection is already established. */
task
->
tk_status
=
0
;
break
;
case
-
EPIPE
:
xprt_close
(
xprt
);
case
-
ECONNREFUSED
:
case
-
ECONNRESET
:
case
-
ENOTCONN
:
if
(
!
task
->
tk_client
->
cl_softrtry
)
{
rpc_delay
(
task
,
RPC_REESTABLISH_TIMEOUT
);
task
->
tk_status
=
-
ENOTCONN
;
goto
out_write
;
break
;
}
default:
/* Report myriad other possible returns. If this file
* system is soft mounted, just error out, like Solaris. */
xprt_close
(
xprt
);
if
(
task
->
tk_client
->
cl_softrtry
)
{
printk
(
KERN_WARNING
"RPC: error %d connecting to server %s, exiting
\n
"
,
-
status
,
task
->
tk_client
->
cl_server
);
task
->
tk_status
=
-
EIO
;
}
else
{
printk
(
KERN_WARNING
"RPC: error %d connecting to server %s
\n
"
,
goto
out_write
;
}
printk
(
KERN_WARNING
"RPC: error %d connecting to server %s
\n
"
,
-
status
,
task
->
tk_client
->
cl_server
);
/* This will prevent anybody else from reconnecting */
rpc_delay
(
task
,
RPC_REESTABLISH_TIMEOUT
);
task
->
tk_status
=
status
;
}
break
;
}
return
;
out_write:
xprt_release_write
(
xprt
,
task
);
}
...
...
@@ -519,33 +504,32 @@ xprt_connect(struct rpc_task *task)
* We arrive here when awoken from waiting on connection establishment.
*/
static
void
xprt_conn_status
(
struct
rpc_task
*
task
)
xprt_conn
ect
_status
(
struct
rpc_task
*
task
)
{
struct
rpc_xprt
*
xprt
=
task
->
tk_xprt
;
switch
(
task
->
tk_status
)
{
case
0
:
dprintk
(
"RPC: %4d xprt_conn_status: connection established
\n
"
,
if
(
task
->
tk_status
>=
0
)
{
dprintk
(
"RPC: %4d xprt_connect_status: connection established
\n
"
,
task
->
tk_pid
);
goto
out
;
return
;
}
/* if soft mounted, just cause this RPC to fail */
if
(
task
->
tk_client
->
cl_softrtry
)
task
->
tk_status
=
-
EIO
;
switch
(
task
->
tk_status
)
{
case
-
ENOTCONN
:
rpc_delay
(
task
,
RPC_REESTABLISH_TIMEOUT
);
return
;
case
-
ETIMEDOUT
:
dprintk
(
"RPC: %4d xprt_conn_status: timed out
\n
"
,
dprintk
(
"RPC: %4d xprt_conn
ect
_status: timed out
\n
"
,
task
->
tk_pid
);
/* prevent TCP from continuing to retry SYNs */
xprt_close
(
xprt
);
break
;
default:
printk
(
KERN_ERR
"RPC: error %d connecting to server %s
\n
"
,
-
task
->
tk_status
,
task
->
tk_client
->
cl_server
);
xprt_close
(
xprt
);
rpc_delay
(
task
,
RPC_REESTABLISH_TIMEOUT
);
break
;
}
/* if soft mounted, cause this RPC to fail */
if
(
task
->
tk_client
->
cl_softrtry
)
task
->
tk_status
=
-
EIO
;
out:
xprt_release_write
(
xprt
,
task
);
}
...
...
@@ -695,6 +679,7 @@ udp_data_ready(struct sock *sk, int len)
struct
sk_buff
*
skb
;
int
err
,
repsize
,
copied
;
read_lock
(
&
sk
->
callback_lock
);
dprintk
(
"RPC: udp_data_ready...
\n
"
);
if
(
!
(
xprt
=
xprt_from_sock
(
sk
)))
{
printk
(
"RPC: udp_data_ready request not found!
\n
"
);
...
...
@@ -745,6 +730,7 @@ udp_data_ready(struct sock *sk, int len)
out:
if
(
sk
->
sleep
&&
waitqueue_active
(
sk
->
sleep
))
wake_up_interruptible
(
sk
->
sleep
);
read_unlock
(
&
sk
->
callback_lock
);
}
/*
...
...
@@ -939,7 +925,7 @@ tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
}
/* Skip over any trailing bytes on short reads */
tcp_read_discard
(
xprt
,
&
desc
);
}
while
(
desc
.
count
&&
xprt_connected
(
xprt
)
);
}
while
(
desc
.
count
);
dprintk
(
"RPC: tcp_data_recv done
\n
"
);
return
len
-
desc
.
count
;
}
...
...
@@ -949,18 +935,21 @@ static void tcp_data_ready(struct sock *sk, int bytes)
struct
rpc_xprt
*
xprt
;
read_descriptor_t
rd_desc
;
read_lock
(
&
sk
->
callback_lock
);
dprintk
(
"RPC: tcp_data_ready...
\n
"
);
if
(
!
(
xprt
=
xprt_from_sock
(
sk
)))
{
printk
(
"RPC: tcp_data_ready socket info not found!
\n
"
);
return
;
goto
out
;
}
if
(
xprt
->
shutdown
)
return
;
goto
out
;
/* We use rd_desc to pass struct xprt to tcp_data_recv */
rd_desc
.
buf
=
(
char
*
)
xprt
;
rd_desc
.
count
=
65536
;
tcp_read_sock
(
sk
,
&
rd_desc
,
tcp_data_recv
);
out:
read_unlock
(
&
sk
->
callback_lock
);
}
static
void
...
...
@@ -968,6 +957,7 @@ tcp_state_change(struct sock *sk)
{
struct
rpc_xprt
*
xprt
;
read_lock
(
&
sk
->
callback_lock
);
if
(
!
(
xprt
=
xprt_from_sock
(
sk
)))
goto
out
;
dprintk
(
"RPC: tcp_state_change client %p...
\n
"
,
xprt
);
...
...
@@ -977,19 +967,19 @@ tcp_state_change(struct sock *sk)
switch
(
sk
->
state
)
{
case
TCP_ESTABLISHED
:
if
(
xprt_test_and_set_connected
(
xprt
))
break
;
spin_lock_bh
(
&
xprt
->
sock_lock
);
if
(
!
xprt_test_and_set_connected
(
xprt
))
{
/* Reset TCP record info */
xprt
->
tcp_offset
=
0
;
xprt
->
tcp_reclen
=
0
;
xprt
->
tcp_copied
=
0
;
xprt
->
tcp_flags
=
XPRT_COPY_RECM
|
XPRT_COPY_XID
;
spin_lock
(
&
xprt
->
sock_lock
);
if
(
xprt
->
snd_task
&&
xprt
->
snd_task
->
tk_rpcwait
==
&
xprt
->
pending
)
if
(
xprt
->
snd_task
)
rpc_wake_up_task
(
xprt
->
snd_task
);
spin_unlock
(
&
xprt
->
sock_lock
);
rpc_wake_up
(
&
xprt
->
pending
);
}
spin_unlock_bh
(
&
xprt
->
sock_lock
);
break
;
case
TCP_SYN_SENT
:
case
TCP_SYN_RECV
:
...
...
@@ -1001,6 +991,7 @@ tcp_state_change(struct sock *sk)
out:
if
(
sk
->
sleep
&&
waitqueue_active
(
sk
->
sleep
))
wake_up_interruptible_all
(
sk
->
sleep
);
read_unlock
(
&
sk
->
callback_lock
);
}
/*
...
...
@@ -1015,24 +1006,25 @@ xprt_write_space(struct sock *sk)
struct
rpc_xprt
*
xprt
;
struct
socket
*
sock
;
read_lock
(
&
sk
->
callback_lock
);
if
(
!
(
xprt
=
xprt_from_sock
(
sk
))
||
!
(
sock
=
sk
->
socket
))
return
;
goto
out
;
if
(
xprt
->
shutdown
)
return
;
goto
out
;
/* Wait until we have enough socket memory */
if
(
xprt
->
stream
)
{
/* from net/ipv4/tcp.c:tcp_write_space */
if
(
tcp_wspace
(
sk
)
<
tcp_min_write_space
(
sk
))
return
;
goto
out
;
}
else
{
/* from net/core/sock.c:sock_def_write_space */
if
(
!
sock_writeable
(
sk
))
return
;
goto
out
;
}
if
(
!
test_and_clear_bit
(
SOCK_NOSPACE
,
&
sock
->
flags
))
return
;
goto
out
;
spin_lock_bh
(
&
xprt
->
sock_lock
);
if
(
xprt
->
snd_task
&&
xprt
->
snd_task
->
tk_rpcwait
==
&
xprt
->
pending
)
...
...
@@ -1040,6 +1032,8 @@ xprt_write_space(struct sock *sk)
spin_unlock_bh
(
&
xprt
->
sock_lock
);
if
(
sk
->
sleep
&&
waitqueue_active
(
sk
->
sleep
))
wake_up_interruptible
(
sk
->
sleep
);
out:
read_unlock
(
&
sk
->
callback_lock
);
}
/*
...
...
@@ -1107,9 +1101,6 @@ xprt_prepare_transmit(struct rpc_task *task)
if
(
xprt
->
shutdown
)
return
-
EIO
;
if
(
!
xprt_connected
(
xprt
))
return
-
ENOTCONN
;
if
(
task
->
tk_rpcwait
)
rpc_remove_wait_queue
(
task
);
...
...
@@ -1118,6 +1109,12 @@ xprt_prepare_transmit(struct rpc_task *task)
err
=
-
EAGAIN
;
goto
out_unlock
;
}
if
(
!
xprt_connected
(
xprt
))
{
err
=
-
ENOTCONN
;
goto
out_unlock
;
}
if
(
list_empty
(
&
req
->
rq_list
))
{
list_add_tail
(
&
req
->
rq_list
,
&
xprt
->
recv
);
req
->
rq_received
=
0
;
...
...
@@ -1192,7 +1189,10 @@ xprt_transmit(struct rpc_task *task)
if
(
test_bit
(
SOCK_ASYNC_NOSPACE
,
&
xprt
->
sock
->
flags
))
{
/* Protect against races with xprt_write_space */
spin_lock_bh
(
&
xprt
->
sock_lock
);
if
(
test_bit
(
SOCK_NOSPACE
,
&
xprt
->
sock
->
flags
))
{
/* Don't race with disconnect */
if
(
!
xprt_connected
(
xprt
))
task
->
tk_status
=
-
ENOTCONN
;
else
if
(
test_bit
(
SOCK_NOSPACE
,
&
xprt
->
sock
->
flags
))
{
task
->
tk_timeout
=
req
->
rq_timeout
.
to_current
;
rpc_sleep_on
(
&
xprt
->
pending
,
task
,
NULL
,
NULL
);
}
...
...
@@ -1203,20 +1203,17 @@ xprt_transmit(struct rpc_task *task)
rpc_delay
(
task
,
HZ
>>
4
);
return
;
case
-
ECONNREFUSED
:
case
-
ENOTCONN
:
if
(
!
xprt
->
stream
)
{
task
->
tk_timeout
=
RPC_REESTABLISH_TIMEOUT
;
rpc_sleep_on
(
&
xprt
->
sending
,
task
,
NULL
,
NULL
);
case
-
ENOTCONN
:
return
;
}
/* fall through */
default:
if
(
xprt
->
stream
)
xprt_disconnect
(
xprt
);
req
->
rq_bytes_sent
=
0
;
}
out_release:
xprt_release_write
(
xprt
,
task
);
req
->
rq_bytes_sent
=
0
;
return
;
out_receive:
dprintk
(
"RPC: %4d xmit complete
\n
"
,
task
->
tk_pid
);
...
...
@@ -1230,10 +1227,14 @@ xprt_transmit(struct rpc_task *task)
}
else
task
->
tk_timeout
=
req
->
rq_timeout
.
to_current
;
spin_lock_bh
(
&
xprt
->
sock_lock
);
if
(
!
req
->
rq_received
)
/* Don't race with disconnect */
if
(
!
xprt_connected
(
xprt
))
task
->
tk_status
=
-
ENOTCONN
;
else
if
(
!
req
->
rq_received
)
rpc_sleep_on
(
&
xprt
->
pending
,
task
,
NULL
,
xprt_timer
);
__xprt_release_write
(
xprt
,
task
);
spin_unlock_bh
(
&
xprt
->
sock_lock
);
req
->
rq_bytes_sent
=
0
;
}
/*
...
...
@@ -1417,6 +1418,9 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
req
->
rq_next
=
NULL
;
xprt
->
free
=
xprt
->
slot
;
/* Check whether we want to use a reserved port */
xprt
->
resvport
=
capable
(
CAP_NET_BIND_SERVICE
)
?
1
:
0
;
dprintk
(
"RPC: created transport %p
\n
"
,
xprt
);
return
xprt
;
...
...
@@ -1430,6 +1434,12 @@ xprt_bindresvport(struct socket *sock)
{
struct
sockaddr_in
myaddr
;
int
err
,
port
;
kernel_cap_t
saved_cap
=
current
->
cap_effective
;
/* Override capabilities.
* They were checked in xprt_create_proto i.e. at mount time
*/
cap_raise
(
current
->
cap_effective
,
CAP_NET_BIND_SERVICE
);
memset
(
&
myaddr
,
0
,
sizeof
(
myaddr
));
myaddr
.
sin_family
=
AF_INET
;
...
...
@@ -1439,6 +1449,7 @@ xprt_bindresvport(struct socket *sock)
err
=
sock
->
ops
->
bind
(
sock
,
(
struct
sockaddr
*
)
&
myaddr
,
sizeof
(
myaddr
));
}
while
(
err
==
-
EADDRINUSE
&&
--
port
>
0
);
current
->
cap_effective
=
saved_cap
;
if
(
err
<
0
)
printk
(
"RPC: Can't bind to reserved port (%d).
\n
"
,
-
err
);
...
...
@@ -1454,6 +1465,7 @@ xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock)
if
(
xprt
->
inet
)
return
;
write_lock_bh
(
&
sk
->
callback_lock
);
sk
->
user_data
=
xprt
;
xprt
->
old_data_ready
=
sk
->
data_ready
;
xprt
->
old_state_change
=
sk
->
state_change
;
...
...
@@ -1474,6 +1486,7 @@ xprt_bind_socket(struct rpc_xprt *xprt, struct socket *sock)
/* Reset to new socket */
xprt
->
sock
=
sock
;
xprt
->
inet
=
sk
;
write_unlock_bh
(
&
sk
->
callback_lock
);
return
;
}
...
...
@@ -1544,16 +1557,6 @@ xprt_create_proto(int proto, struct sockaddr_in *sap, struct rpc_timeout *to)
if
(
!
xprt
)
goto
out_bad
;
xprt
->
resvport
=
capable
(
CAP_NET_BIND_SERVICE
)
?
1
:
0
;
if
(
!
xprt
->
stream
)
{
struct
socket
*
sock
;
sock
=
xprt_create_socket
(
proto
,
to
,
xprt
->
resvport
);
if
(
!
sock
)
goto
out_bad
;
xprt_bind_socket
(
xprt
,
sock
);
}
dprintk
(
"RPC: xprt_create_proto created xprt %p
\n
"
,
xprt
);
return
xprt
;
out_bad:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment