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
7285f2d2
Commit
7285f2d2
authored
Dec 03, 2009
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'devel' into linux-next
parents
0b08b075
44ed3556
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
261 additions
and
114 deletions
+261
-114
fs/nfs/callback.c
fs/nfs/callback.c
+0
-12
fs/nfs/dir.c
fs/nfs/dir.c
+29
-38
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+7
-0
fs/nfs/nfs4state.c
fs/nfs/nfs4state.c
+8
-0
fs/nfs/super.c
fs/nfs/super.c
+82
-22
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+1
-1
include/linux/sunrpc/sched.h
include/linux/sunrpc/sched.h
+2
-0
net/sunrpc/addr.c
net/sunrpc/addr.c
+1
-9
net/sunrpc/clnt.c
net/sunrpc/clnt.c
+46
-8
net/sunrpc/rpcb_clnt.c
net/sunrpc/rpcb_clnt.c
+81
-23
net/sunrpc/sunrpc_syms.c
net/sunrpc/sunrpc_syms.c
+3
-0
net/sunrpc/xprtsock.c
net/sunrpc/xprtsock.c
+1
-1
No files found.
fs/nfs/callback.c
View file @
7285f2d2
...
...
@@ -78,11 +78,6 @@ nfs4_callback_svc(void *vrqstp)
set_freezable
();
/*
* FIXME: do we really need to run this under the BKL? If so, please
* add a comment about what it's intended to protect.
*/
lock_kernel
();
while
(
!
kthread_should_stop
())
{
/*
* Listen for a request on the socket
...
...
@@ -104,7 +99,6 @@ nfs4_callback_svc(void *vrqstp)
preverr
=
err
;
svc_process
(
rqstp
);
}
unlock_kernel
();
return
0
;
}
...
...
@@ -160,11 +154,6 @@ nfs41_callback_svc(void *vrqstp)
set_freezable
();
/*
* FIXME: do we really need to run this under the BKL? If so, please
* add a comment about what it's intended to protect.
*/
lock_kernel
();
while
(
!
kthread_should_stop
())
{
prepare_to_wait
(
&
serv
->
sv_cb_waitq
,
&
wq
,
TASK_INTERRUPTIBLE
);
spin_lock_bh
(
&
serv
->
sv_cb_lock
);
...
...
@@ -183,7 +172,6 @@ nfs41_callback_svc(void *vrqstp)
}
finish_wait
(
&
serv
->
sv_cb_waitq
,
&
wq
);
}
unlock_kernel
();
return
0
;
}
...
...
fs/nfs/dir.c
View file @
7285f2d2
...
...
@@ -1579,55 +1579,46 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct
dentry
*
dentry
=
NULL
,
*
rehash
=
NULL
;
int
error
=
-
EBUSY
;
/*
* To prevent any new references to the target during the rename,
* we unhash the dentry and free the inode in advance.
*/
if
(
!
d_unhashed
(
new_dentry
))
{
d_drop
(
new_dentry
);
rehash
=
new_dentry
;
}
dfprintk
(
VFS
,
"NFS: rename(%s/%s -> %s/%s, ct=%d)
\n
"
,
old_dentry
->
d_parent
->
d_name
.
name
,
old_dentry
->
d_name
.
name
,
new_dentry
->
d_parent
->
d_name
.
name
,
new_dentry
->
d_name
.
name
,
atomic_read
(
&
new_dentry
->
d_count
));
/*
* First check whether the target is busy ... we can't
* safely do _any_ rename if the target is in use.
*
* For files, make a copy of the dentry and then do a
* silly-rename. If the silly-rename succeeds, the
* copied dentry is hashed and becomes the new target.
* For non-directories, check whether the target is busy and if so,
* make a copy of the dentry and then do a silly-rename. If the
* silly-rename succeeds, the copied dentry is hashed and becomes
* the new target.
*/
if
(
!
new_inode
)
goto
go_ahead
;
if
(
S_ISDIR
(
new_inode
->
i_mode
))
{
error
=
-
EISDIR
;
if
(
!
S_ISDIR
(
old_inode
->
i_mode
))
goto
out
;
}
else
if
(
atomic_read
(
&
new_dentry
->
d_count
)
>
2
)
{
int
err
;
/* copy the target dentry's name */
dentry
=
d_alloc
(
new_dentry
->
d_parent
,
&
new_dentry
->
d_name
);
if
(
!
dentry
)
goto
out
;
if
(
new_inode
&&
!
S_ISDIR
(
new_inode
->
i_mode
))
{
/*
* To prevent any new references to the target during the
* rename, we unhash the dentry in advance.
*/
if
(
!
d_unhashed
(
new_dentry
))
{
d_drop
(
new_dentry
);
rehash
=
new_dentry
;
}
if
(
atomic_read
(
&
new_dentry
->
d_count
)
>
2
)
{
int
err
;
/* copy the target dentry's name */
dentry
=
d_alloc
(
new_dentry
->
d_parent
,
&
new_dentry
->
d_name
);
if
(
!
dentry
)
goto
out
;
/* silly-rename the existing target ... */
err
=
nfs_sillyrename
(
new_dir
,
new_dentry
);
if
(
!
err
)
{
new_dentry
=
rehash
=
dentry
;
/* silly-rename the existing target ... */
err
=
nfs_sillyrename
(
new_dir
,
new_dentry
);
if
(
err
)
goto
out
;
new_dentry
=
dentry
;
new_inode
=
NULL
;
/* instantiate the replacement target */
d_instantiate
(
new_dentry
,
NULL
);
}
else
if
(
atomic_read
(
&
new_dentry
->
d_count
)
>
1
)
/* dentry still busy? */
goto
out
;
}
}
go_ahead:
/*
* ... prune child dentries and writebacks if needed.
*/
...
...
fs/nfs/nfs4proc.c
View file @
7285f2d2
...
...
@@ -275,6 +275,13 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
/* FALLTHROUGH */
#endif
/* !defined(CONFIG_NFS_V4_1) */
case
-
NFS4ERR_FILE_OPEN
:
if
(
exception
->
timeout
>
HZ
)
{
/* We have retried a decent amount, time to
* fail
*/
ret
=
-
EBUSY
;
break
;
}
case
-
NFS4ERR_GRACE
:
case
-
NFS4ERR_DELAY
:
ret
=
nfs4_delay
(
server
->
client
,
&
exception
->
timeout
);
...
...
fs/nfs/nfs4state.c
View file @
7285f2d2
...
...
@@ -877,6 +877,10 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
case
-
NFS4ERR_EXPIRED
:
case
-
NFS4ERR_NO_GRACE
:
case
-
NFS4ERR_STALE_CLIENTID
:
case
-
NFS4ERR_BADSESSION
:
case
-
NFS4ERR_BADSLOT
:
case
-
NFS4ERR_BAD_HIGH_SLOT
:
case
-
NFS4ERR_CONN_NOT_BOUND_TO_SESSION
:
goto
out
;
default:
printk
(
KERN_ERR
"%s: unhandled error %d. Zeroing state
\n
"
,
...
...
@@ -959,6 +963,10 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
case
-
NFS4ERR_NO_GRACE
:
nfs4_state_mark_reclaim_nograce
(
sp
->
so_client
,
state
);
case
-
NFS4ERR_STALE_CLIENTID
:
case
-
NFS4ERR_BADSESSION
:
case
-
NFS4ERR_BADSLOT
:
case
-
NFS4ERR_BAD_HIGH_SLOT
:
case
-
NFS4ERR_CONN_NOT_BOUND_TO_SESSION
:
goto
out_err
;
}
nfs4_put_open_state
(
state
);
...
...
fs/nfs/super.c
View file @
7285f2d2
...
...
@@ -175,14 +175,16 @@ static const match_table_t nfs_mount_option_tokens = {
};
enum
{
Opt_xprt_udp
,
Opt_xprt_
tcp
,
Opt_xprt_rdma
,
Opt_xprt_udp
,
Opt_xprt_
udp6
,
Opt_xprt_tcp
,
Opt_xprt_tcp6
,
Opt_xprt_rdma
,
Opt_xprt_err
};
static
const
match_table_t
nfs_xprt_protocol_tokens
=
{
{
Opt_xprt_udp
,
"udp"
},
{
Opt_xprt_udp6
,
"udp6"
},
{
Opt_xprt_tcp
,
"tcp"
},
{
Opt_xprt_tcp6
,
"tcp6"
},
{
Opt_xprt_rdma
,
"rdma"
},
{
Opt_xprt_err
,
NULL
}
...
...
@@ -492,6 +494,45 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
return
sec_flavours
[
i
].
str
;
}
static
void
nfs_show_mountd_netid
(
struct
seq_file
*
m
,
struct
nfs_server
*
nfss
,
int
showdefaults
)
{
struct
sockaddr
*
sap
=
(
struct
sockaddr
*
)
&
nfss
->
mountd_address
;
seq_printf
(
m
,
",mountproto="
);
switch
(
sap
->
sa_family
)
{
case
AF_INET
:
switch
(
nfss
->
mountd_protocol
)
{
case
IPPROTO_UDP
:
seq_printf
(
m
,
RPCBIND_NETID_UDP
);
break
;
case
IPPROTO_TCP
:
seq_printf
(
m
,
RPCBIND_NETID_TCP
);
break
;
default:
if
(
showdefaults
)
seq_printf
(
m
,
"auto"
);
}
break
;
case
AF_INET6
:
switch
(
nfss
->
mountd_protocol
)
{
case
IPPROTO_UDP
:
seq_printf
(
m
,
RPCBIND_NETID_UDP6
);
break
;
case
IPPROTO_TCP
:
seq_printf
(
m
,
RPCBIND_NETID_TCP6
);
break
;
default:
if
(
showdefaults
)
seq_printf
(
m
,
"auto"
);
}
break
;
default:
if
(
showdefaults
)
seq_printf
(
m
,
"auto"
);
}
}
static
void
nfs_show_mountd_options
(
struct
seq_file
*
m
,
struct
nfs_server
*
nfss
,
int
showdefaults
)
{
...
...
@@ -505,7 +546,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
}
case
AF_INET6
:
{
struct
sockaddr_in6
*
sin6
=
(
struct
sockaddr_in6
*
)
sap
;
seq_printf
(
m
,
",mountaddr=%pI6"
,
&
sin6
->
sin6_addr
);
seq_printf
(
m
,
",mountaddr=%pI6
c
"
,
&
sin6
->
sin6_addr
);
break
;
}
default:
...
...
@@ -518,17 +559,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
if
(
nfss
->
mountd_port
||
showdefaults
)
seq_printf
(
m
,
",mountport=%u"
,
nfss
->
mountd_port
);
switch
(
nfss
->
mountd_protocol
)
{
case
IPPROTO_UDP
:
seq_printf
(
m
,
",mountproto=udp"
);
break
;
case
IPPROTO_TCP
:
seq_printf
(
m
,
",mountproto=tcp"
);
break
;
default:
if
(
showdefaults
)
seq_printf
(
m
,
",mountproto=auto"
);
}
nfs_show_mountd_netid
(
m
,
nfss
,
showdefaults
);
}
/*
...
...
@@ -578,7 +609,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
seq_puts
(
m
,
nfs_infop
->
nostr
);
}
seq_printf
(
m
,
",proto=%s"
,
rpc_peeraddr2str
(
nfss
->
client
,
RPC_DISPLAY_
PROTO
));
rpc_peeraddr2str
(
nfss
->
client
,
RPC_DISPLAY_
NETID
));
if
(
version
==
4
)
{
if
(
nfss
->
port
!=
NFS_PORT
)
seq_printf
(
m
,
",port=%u"
,
nfss
->
port
);
...
...
@@ -714,8 +745,6 @@ static void nfs_umount_begin(struct super_block *sb)
struct
nfs_server
*
server
;
struct
rpc_clnt
*
rpc
;
lock_kernel
();
server
=
NFS_SB
(
sb
);
/* -EIO all pending I/O */
rpc
=
server
->
client_acl
;
...
...
@@ -724,8 +753,6 @@ static void nfs_umount_begin(struct super_block *sb)
rpc
=
server
->
client
;
if
(
!
IS_ERR
(
rpc
))
rpc_killall_tasks
(
rpc
);
unlock_kernel
();
}
static
struct
nfs_parsed_mount_data
*
nfs_alloc_parsed_mount_data
(
unsigned
int
version
)
...
...
@@ -734,8 +761,6 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
data
=
kzalloc
(
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
data
)
{
data
->
rsize
=
NFS_MAX_FILE_IO_SIZE
;
data
->
wsize
=
NFS_MAX_FILE_IO_SIZE
;
data
->
acregmin
=
NFS_DEF_ACREGMIN
;
data
->
acregmax
=
NFS_DEF_ACREGMAX
;
data
->
acdirmin
=
NFS_DEF_ACDIRMIN
;
...
...
@@ -887,6 +912,8 @@ static int nfs_parse_mount_options(char *raw,
{
char
*
p
,
*
string
,
*
secdata
;
int
rc
,
sloppy
=
0
,
invalid_option
=
0
;
unsigned
short
protofamily
=
AF_UNSPEC
;
unsigned
short
mountfamily
=
AF_UNSPEC
;
if
(
!
raw
)
{
dfprintk
(
MOUNT
,
"NFS: mount options string was NULL.
\n
"
);
...
...
@@ -1232,12 +1259,17 @@ static int nfs_parse_mount_options(char *raw,
token
=
match_token
(
string
,
nfs_xprt_protocol_tokens
,
args
);
protofamily
=
AF_INET
;
switch
(
token
)
{
case
Opt_xprt_udp6
:
protofamily
=
AF_INET6
;
case
Opt_xprt_udp
:
mnt
->
flags
&=
~
NFS_MOUNT_TCP
;
mnt
->
nfs_server
.
protocol
=
XPRT_TRANSPORT_UDP
;
kfree
(
string
);
break
;
case
Opt_xprt_tcp6
:
protofamily
=
AF_INET6
;
case
Opt_xprt_tcp
:
mnt
->
flags
|=
NFS_MOUNT_TCP
;
mnt
->
nfs_server
.
protocol
=
XPRT_TRANSPORT_TCP
;
...
...
@@ -1265,10 +1297,15 @@ static int nfs_parse_mount_options(char *raw,
nfs_xprt_protocol_tokens
,
args
);
kfree
(
string
);
mountfamily
=
AF_INET
;
switch
(
token
)
{
case
Opt_xprt_udp6
:
mountfamily
=
AF_INET6
;
case
Opt_xprt_udp
:
mnt
->
mount_server
.
protocol
=
XPRT_TRANSPORT_UDP
;
break
;
case
Opt_xprt_tcp6
:
mountfamily
=
AF_INET6
;
case
Opt_xprt_tcp
:
mnt
->
mount_server
.
protocol
=
XPRT_TRANSPORT_TCP
;
break
;
...
...
@@ -1367,8 +1404,33 @@ static int nfs_parse_mount_options(char *raw,
if
(
!
sloppy
&&
invalid_option
)
return
0
;
/*
* verify that any proto=/mountproto= options match the address
* familiies in the addr=/mountaddr= options.
*/
if
(
protofamily
!=
AF_UNSPEC
&&
protofamily
!=
mnt
->
nfs_server
.
address
.
ss_family
)
goto
out_proto_mismatch
;
if
(
mountfamily
!=
AF_UNSPEC
)
{
if
(
mnt
->
mount_server
.
addrlen
)
{
if
(
mountfamily
!=
mnt
->
mount_server
.
address
.
ss_family
)
goto
out_mountproto_mismatch
;
}
else
{
if
(
mountfamily
!=
mnt
->
nfs_server
.
address
.
ss_family
)
goto
out_mountproto_mismatch
;
}
}
return
1
;
out_mountproto_mismatch:
printk
(
KERN_INFO
"NFS: mount server address does not match mountproto= "
"option
\n
"
);
return
0
;
out_proto_mismatch:
printk
(
KERN_INFO
"NFS: server address does not match proto= option
\n
"
);
return
0
;
out_invalid_address:
printk
(
KERN_INFO
"NFS: bad IP address specified: %s
\n
"
,
p
);
return
0
;
...
...
@@ -1881,7 +1943,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
if
(
data
==
NULL
)
return
-
ENOMEM
;
lock_kernel
();
/* fill out struct with values from existing mount */
data
->
flags
=
nfss
->
flags
;
data
->
rsize
=
nfss
->
rsize
;
...
...
@@ -1907,7 +1968,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
error
=
nfs_compare_remount_data
(
nfss
,
data
);
out:
kfree
(
data
);
unlock_kernel
();
return
error
;
}
...
...
include/linux/nfs_xdr.h
View file @
7285f2d2
...
...
@@ -170,8 +170,8 @@ struct nfs4_sequence_args {
struct
nfs4_sequence_res
{
struct
nfs4_session
*
sr_session
;
u8
sr_slotid
;
/* slot used to send request */
unsigned
long
sr_renewal_time
;
int
sr_status
;
/* sequence operation status */
unsigned
long
sr_renewal_time
;
};
struct
nfs4_get_lease_time_args
{
...
...
include/linux/sunrpc/sched.h
View file @
7285f2d2
...
...
@@ -130,12 +130,14 @@ struct rpc_task_setup {
#define RPC_TASK_DYNAMIC 0x0080
/* task was kmalloc'ed */
#define RPC_TASK_KILLED 0x0100
/* task was killed */
#define RPC_TASK_SOFT 0x0200
/* Use soft timeouts */
#define RPC_TASK_SOFTCONN 0x0400
/* Fail if can't connect */
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
#define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN)
#define RPC_TASK_RUNNING 0
#define RPC_TASK_QUEUED 1
...
...
net/sunrpc/addr.c
View file @
7285f2d2
...
...
@@ -55,16 +55,8 @@ static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
/*
* RFC 4291, Section 2.2.1
*
* To keep the result as short as possible, especially
* since we don't shorthand, we don't want leading zeros
* in each halfword, so avoid %pI6.
*/
return
snprintf
(
buf
,
buflen
,
"%x:%x:%x:%x:%x:%x:%x:%x"
,
ntohs
(
addr
->
s6_addr16
[
0
]),
ntohs
(
addr
->
s6_addr16
[
1
]),
ntohs
(
addr
->
s6_addr16
[
2
]),
ntohs
(
addr
->
s6_addr16
[
3
]),
ntohs
(
addr
->
s6_addr16
[
4
]),
ntohs
(
addr
->
s6_addr16
[
5
]),
ntohs
(
addr
->
s6_addr16
[
6
]),
ntohs
(
addr
->
s6_addr16
[
7
]));
return
snprintf
(
buf
,
buflen
,
"%pI6c"
,
addr
);
}
static
size_t
rpc_ntop6
(
const
struct
sockaddr
*
sap
,
...
...
net/sunrpc/clnt.c
View file @
7285f2d2
...
...
@@ -79,7 +79,7 @@ static void call_connect_status(struct rpc_task *task);
static
__be32
*
rpc_encode_header
(
struct
rpc_task
*
task
);
static
__be32
*
rpc_verify_header
(
struct
rpc_task
*
task
);
static
int
rpc_ping
(
struct
rpc_clnt
*
clnt
,
int
flags
);
static
int
rpc_ping
(
struct
rpc_clnt
*
clnt
);
static
void
rpc_register_client
(
struct
rpc_clnt
*
clnt
)
{
...
...
@@ -340,7 +340,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
return
clnt
;
if
(
!
(
args
->
flags
&
RPC_CLNT_CREATE_NOPING
))
{
int
err
=
rpc_ping
(
clnt
,
RPC_TASK_SOFT
);
int
err
=
rpc_ping
(
clnt
);
if
(
err
!=
0
)
{
rpc_shutdown_client
(
clnt
);
return
ERR_PTR
(
err
);
...
...
@@ -528,7 +528,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
clnt
->
cl_prog
=
program
->
number
;
clnt
->
cl_vers
=
version
->
number
;
clnt
->
cl_stats
=
program
->
stats
;
err
=
rpc_ping
(
clnt
,
RPC_TASK_SOFT
);
err
=
rpc_ping
(
clnt
);
if
(
err
!=
0
)
{
rpc_shutdown_client
(
clnt
);
clnt
=
ERR_PTR
(
err
);
...
...
@@ -1060,7 +1060,7 @@ call_bind_status(struct rpc_task *task)
goto
retry_timeout
;
case
-
EPFNOSUPPORT
:
/* server doesn't support any rpcbind version we know of */
dprintk
(
"RPC: %5u
remote rpcbind service unavailabl
e
\n
"
,
dprintk
(
"RPC: %5u
unrecognized remote rpcbind servic
e
\n
"
,
task
->
tk_pid
);
break
;
case
-
EPROTONOSUPPORT
:
...
...
@@ -1069,6 +1069,21 @@ call_bind_status(struct rpc_task *task)
task
->
tk_status
=
0
;
task
->
tk_action
=
call_bind
;
return
;
case
-
ECONNREFUSED
:
/* connection problems */
case
-
ECONNRESET
:
case
-
ENOTCONN
:
case
-
EHOSTDOWN
:
case
-
EHOSTUNREACH
:
case
-
ENETUNREACH
:
case
-
EPIPE
:
dprintk
(
"RPC: %5u remote rpcbind unreachable: %d
\n
"
,
task
->
tk_pid
,
task
->
tk_status
);
if
(
!
RPC_IS_SOFTCONN
(
task
))
{
rpc_delay
(
task
,
5
*
HZ
);
goto
retry_timeout
;
}
status
=
task
->
tk_status
;
break
;
default:
dprintk
(
"RPC: %5u unrecognized rpcbind error (%d)
\n
"
,
task
->
tk_pid
,
-
task
->
tk_status
);
...
...
@@ -1180,11 +1195,25 @@ static void
call_transmit_status
(
struct
rpc_task
*
task
)
{
task
->
tk_action
=
call_status
;
/*
* Common case: success. Force the compiler to put this
* test first.
*/
if
(
task
->
tk_status
==
0
)
{
xprt_end_transmit
(
task
);
rpc_task_force_reencode
(
task
);
return
;
}
switch
(
task
->
tk_status
)
{
case
-
EAGAIN
:
break
;
default:
dprint_status
(
task
);
xprt_end_transmit
(
task
);
rpc_task_force_reencode
(
task
);
break
;
/*
* Special cases: if we've been waiting on the
* socket's write_space() callback, or if the
...
...
@@ -1192,11 +1221,16 @@ call_transmit_status(struct rpc_task *task)
* then hold onto the transport lock.
*/
case
-
ECONNREFUSED
:
case
-
ECONNRESET
:
case
-
ENOTCONN
:
case
-
EHOSTDOWN
:
case
-
EHOSTUNREACH
:
case
-
ENETUNREACH
:
if
(
RPC_IS_SOFTCONN
(
task
))
{
xprt_end_transmit
(
task
);
rpc_exit
(
task
,
task
->
tk_status
);
break
;
}
case
-
ECONNRESET
:
case
-
ENOTCONN
:
case
-
EPIPE
:
rpc_task_force_reencode
(
task
);
}
...
...
@@ -1346,6 +1380,10 @@ call_timeout(struct rpc_task *task)
dprintk
(
"RPC: %5u call_timeout (major)
\n
"
,
task
->
tk_pid
);
task
->
tk_timeouts
++
;
if
(
RPC_IS_SOFTCONN
(
task
))
{
rpc_exit
(
task
,
-
ETIMEDOUT
);
return
;
}
if
(
RPC_IS_SOFT
(
task
))
{
if
(
clnt
->
cl_chatty
)
printk
(
KERN_NOTICE
"%s: server %s not responding, timed out
\n
"
,
...
...
@@ -1675,14 +1713,14 @@ static struct rpc_procinfo rpcproc_null = {
.
p_decode
=
rpcproc_decode_null
,
};
static
int
rpc_ping
(
struct
rpc_clnt
*
clnt
,
int
flags
)
static
int
rpc_ping
(
struct
rpc_clnt
*
clnt
)
{
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
rpcproc_null
,
};
int
err
;
msg
.
rpc_cred
=
authnull_ops
.
lookup_cred
(
NULL
,
NULL
,
0
);
err
=
rpc_call_sync
(
clnt
,
&
msg
,
flags
);
err
=
rpc_call_sync
(
clnt
,
&
msg
,
RPC_TASK_SOFT
|
RPC_TASK_SOFTCONN
);
put_rpccred
(
msg
.
rpc_cred
);
return
err
;
}
...
...
net/sunrpc/rpcb_clnt.c
View file @
7285f2d2
...
...
@@ -20,6 +20,7 @@
#include <linux/in6.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <net/ipv6.h>
#include <linux/sunrpc/clnt.h>
...
...
@@ -110,6 +111,9 @@ static void rpcb_getport_done(struct rpc_task *, void *);
static
void
rpcb_map_release
(
void
*
data
);
static
struct
rpc_program
rpcb_program
;
static
struct
rpc_clnt
*
rpcb_local_clnt
;
static
struct
rpc_clnt
*
rpcb_local_clnt4
;
struct
rpcbind_args
{
struct
rpc_xprt
*
r_xprt
;
...
...
@@ -163,21 +167,60 @@ static const struct sockaddr_in rpcb_inaddr_loopback = {
.
sin_port
=
htons
(
RPCBIND_PORT
),
};
static
struct
rpc_clnt
*
rpcb_create_local
(
struct
sockaddr
*
addr
,
size_t
addrlen
,
u32
version
)
static
DEFINE_MUTEX
(
rpcb_create_local_mutex
);
/*
* Returns zero on success, otherwise a negative errno value
* is returned.
*/
static
int
rpcb_create_local
(
void
)
{
struct
rpc_create_args
args
=
{
.
protocol
=
XPRT_TRANSPORT_
UD
P
,
.
address
=
addr
,
.
addrsize
=
addrlen
,
.
protocol
=
XPRT_TRANSPORT_
TC
P
,
.
address
=
(
struct
sockaddr
*
)
&
rpcb_inaddr_loopback
,
.
addrsize
=
sizeof
(
rpcb_inaddr_loopback
)
,
.
servername
=
"localhost"
,
.
program
=
&
rpcb_program
,
.
version
=
version
,
.
version
=
RPCBVERS_2
,
.
authflavor
=
RPC_AUTH_UNIX
,
.
flags
=
RPC_CLNT_CREATE_NOPING
,
};
struct
rpc_clnt
*
clnt
,
*
clnt4
;
int
result
=
0
;
if
(
rpcb_local_clnt
)
return
result
;
mutex_lock
(
&
rpcb_create_local_mutex
);
if
(
rpcb_local_clnt
)
goto
out
;
clnt
=
rpc_create
(
&
args
);
if
(
IS_ERR
(
clnt
))
{
dprintk
(
"RPC: failed to create local rpcbind "
"client (errno %ld).
\n
"
,
PTR_ERR
(
clnt
));
result
=
-
PTR_ERR
(
clnt
);
goto
out
;
}
return
rpc_create
(
&
args
);
/*
* This results in an RPC ping. On systems running portmapper,
* the v4 ping will fail. Proceed anyway, but disallow rpcb
* v4 upcalls.
*/
clnt4
=
rpc_bind_new_program
(
clnt
,
&
rpcb_program
,
RPCBVERS_4
);
if
(
IS_ERR
(
clnt4
))
{
dprintk
(
"RPC: failed to create local rpcbind v4 "
"cleint (errno %ld).
\n
"
,
PTR_ERR
(
clnt4
));
clnt4
=
NULL
;
}
rpcb_local_clnt
=
clnt
;
rpcb_local_clnt4
=
clnt4
;
out:
mutex_unlock
(
&
rpcb_create_local_mutex
);
return
result
;
}
static
struct
rpc_clnt
*
rpcb_create
(
char
*
hostname
,
struct
sockaddr
*
srvaddr
,
...
...
@@ -209,22 +252,13 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
return
rpc_create
(
&
args
);
}
static
int
rpcb_register_call
(
const
u32
version
,
struct
rpc_message
*
msg
)
static
int
rpcb_register_call
(
struct
rpc_clnt
*
clnt
,
struct
rpc_message
*
msg
)
{
struct
sockaddr
*
addr
=
(
struct
sockaddr
*
)
&
rpcb_inaddr_loopback
;
size_t
addrlen
=
sizeof
(
rpcb_inaddr_loopback
);
struct
rpc_clnt
*
rpcb_clnt
;
int
result
,
error
=
0
;
msg
->
rpc_resp
=
&
result
;
rpcb_clnt
=
rpcb_create_local
(
addr
,
addrlen
,
version
);
if
(
!
IS_ERR
(
rpcb_clnt
))
{
error
=
rpc_call_sync
(
rpcb_clnt
,
msg
,
0
);
rpc_shutdown_client
(
rpcb_clnt
);
}
else
error
=
PTR_ERR
(
rpcb_clnt
);
error
=
rpc_call_sync
(
clnt
,
msg
,
RPC_TASK_SOFTCONN
);
if
(
error
<
0
)
{
dprintk
(
"RPC: failed to contact local rpcbind "
"server (errno %d).
\n
"
,
-
error
);
...
...
@@ -279,6 +313,11 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
struct
rpc_message
msg
=
{
.
rpc_argp
=
&
map
,
};
int
error
;
error
=
rpcb_create_local
();
if
(
error
)
return
error
;
dprintk
(
"RPC: %sregistering (%u, %u, %d, %u) with local "
"rpcbind
\n
"
,
(
port
?
""
:
"un"
),
...
...
@@ -288,7 +327,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
if
(
port
)
msg
.
rpc_proc
=
&
rpcb_procedures2
[
RPCBPROC_SET
];
return
rpcb_register_call
(
RPCBVERS_2
,
&
msg
);
return
rpcb_register_call
(
rpcb_local_clnt
,
&
msg
);
}
/*
...
...
@@ -313,7 +352,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
if
(
port
)
msg
->
rpc_proc
=
&
rpcb_procedures4
[
RPCBPROC_SET
];
result
=
rpcb_register_call
(
RPCBVERS_
4
,
msg
);
result
=
rpcb_register_call
(
rpcb_local_clnt
4
,
msg
);
kfree
(
map
->
r_addr
);
return
result
;
}
...
...
@@ -340,7 +379,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
if
(
port
)
msg
->
rpc_proc
=
&
rpcb_procedures4
[
RPCBPROC_SET
];
result
=
rpcb_register_call
(
RPCBVERS_
4
,
msg
);
result
=
rpcb_register_call
(
rpcb_local_clnt
4
,
msg
);
kfree
(
map
->
r_addr
);
return
result
;
}
...
...
@@ -356,7 +395,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
map
->
r_addr
=
""
;
msg
->
rpc_proc
=
&
rpcb_procedures4
[
RPCBPROC_UNSET
];
return
rpcb_register_call
(
RPCBVERS_
4
,
msg
);
return
rpcb_register_call
(
rpcb_local_clnt
4
,
msg
);
}
/**
...
...
@@ -414,6 +453,13 @@ int rpcb_v4_register(const u32 program, const u32 version,
struct
rpc_message
msg
=
{
.
rpc_argp
=
&
map
,
};
int
error
;
error
=
rpcb_create_local
();
if
(
error
)
return
error
;
if
(
rpcb_local_clnt4
==
NULL
)
return
-
EPROTONOSUPPORT
;
if
(
address
==
NULL
)
return
rpcb_unregister_all_protofamilies
(
&
msg
);
...
...
@@ -491,7 +537,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
.
rpc_message
=
&
msg
,
.
callback_ops
=
&
rpcb_getport_ops
,
.
callback_data
=
map
,
.
flags
=
RPC_TASK_ASYNC
,
.
flags
=
RPC_TASK_ASYNC
|
RPC_TASK_SOFTCONN
,
};
return
rpc_run_task
(
&
task_setup_data
);
...
...
@@ -1027,3 +1073,15 @@ static struct rpc_program rpcb_program = {
.
version
=
rpcb_version
,
.
stats
=
&
rpcb_stats
,
};
/**
* cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
*
*/
void
cleanup_rpcb_clnt
(
void
)
{
if
(
rpcb_local_clnt4
)
rpc_shutdown_client
(
rpcb_local_clnt4
);
if
(
rpcb_local_clnt
)
rpc_shutdown_client
(
rpcb_local_clnt
);
}
net/sunrpc/sunrpc_syms.c
View file @
7285f2d2
...
...
@@ -24,6 +24,8 @@
extern
struct
cache_detail
ip_map_cache
,
unix_gid_cache
;
extern
void
cleanup_rpcb_clnt
(
void
);
static
int
__init
init_sunrpc
(
void
)
{
...
...
@@ -53,6 +55,7 @@ init_sunrpc(void)
static
void
__exit
cleanup_sunrpc
(
void
)
{
cleanup_rpcb_clnt
();
rpcauth_remove_module
();
cleanup_socket_xprt
();
svc_cleanup_xprt_sock
();
...
...
net/sunrpc/xprtsock.c
View file @
7285f2d2
...
...
@@ -2033,7 +2033,7 @@ static void xs_connect(struct rpc_task *task)
if
(
xprt_test_and_set_connecting
(
xprt
))
return
;
if
(
transport
->
sock
!=
NULL
)
{
if
(
transport
->
sock
!=
NULL
&&
!
RPC_IS_SOFTCONN
(
task
)
)
{
dprintk
(
"RPC: xs_connect delayed xprt %p for %lu "
"seconds
\n
"
,
xprt
,
xprt
->
reestablish_timeout
/
HZ
);
...
...
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