Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
7285f2d2
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
7285f2d2
编写于
12月 03, 2009
作者:
T
Trond Myklebust
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'devel' into linux-next
上级
0b08b075
44ed3556
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
261 addition
and
114 deletion
+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
未找到文件。
fs/nfs/callback.c
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录