Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
47853e7f
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
47853e7f
编写于
1月 06, 2006
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge
git://git.linux-nfs.org/pub/linux/nfs-2.6
上级
221fc10e
9e56904e
变更
62
展开全部
显示空白变更内容
内联
并排
Showing
62 changed file
with
2140 addition
and
1339 deletion
+2140
-1339
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+8
-0
fs/lockd/clntproc.c
fs/lockd/clntproc.c
+22
-19
fs/lockd/host.c
fs/lockd/host.c
+2
-2
fs/lockd/mon.c
fs/lockd/mon.c
+0
-1
fs/lockd/svc.c
fs/lockd/svc.c
+2
-2
fs/lockd/svc4proc.c
fs/lockd/svc4proc.c
+9
-6
fs/lockd/svclock.c
fs/lockd/svclock.c
+22
-20
fs/lockd/svcproc.c
fs/lockd/svcproc.c
+9
-5
fs/lockd/xdr4.c
fs/lockd/xdr4.c
+3
-1
fs/locks.c
fs/locks.c
+8
-12
fs/nfs/Makefile
fs/nfs/Makefile
+1
-0
fs/nfs/callback.c
fs/nfs/callback.c
+2
-1
fs/nfs/callback.h
fs/nfs/callback.h
+1
-0
fs/nfs/callback_proc.c
fs/nfs/callback_proc.c
+3
-1
fs/nfs/delegation.c
fs/nfs/delegation.c
+45
-2
fs/nfs/delegation.h
fs/nfs/delegation.h
+2
-0
fs/nfs/dir.c
fs/nfs/dir.c
+3
-1
fs/nfs/direct.c
fs/nfs/direct.c
+26
-31
fs/nfs/idmap.c
fs/nfs/idmap.c
+9
-0
fs/nfs/inode.c
fs/nfs/inode.c
+113
-65
fs/nfs/mount_clnt.c
fs/nfs/mount_clnt.c
+0
-1
fs/nfs/nfs2xdr.c
fs/nfs/nfs2xdr.c
+10
-11
fs/nfs/nfs3proc.c
fs/nfs/nfs3proc.c
+46
-24
fs/nfs/nfs3xdr.c
fs/nfs/nfs3xdr.c
+1
-1
fs/nfs/nfs4_fs.h
fs/nfs/nfs4_fs.h
+10
-10
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+930
-550
fs/nfs/nfs4renewd.c
fs/nfs/nfs4renewd.c
+12
-2
fs/nfs/nfs4state.c
fs/nfs/nfs4state.c
+104
-79
fs/nfs/nfs4xdr.c
fs/nfs/nfs4xdr.c
+104
-83
fs/nfs/nfsroot.c
fs/nfs/nfsroot.c
+2
-2
fs/nfs/proc.c
fs/nfs/proc.c
+21
-10
fs/nfs/read.c
fs/nfs/read.c
+6
-10
fs/nfs/sysctl.c
fs/nfs/sysctl.c
+84
-0
fs/nfs/unlink.c
fs/nfs/unlink.c
+14
-16
fs/nfs/write.c
fs/nfs/write.c
+45
-44
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4callback.c
+7
-4
include/linux/fs.h
include/linux/fs.h
+1
-1
include/linux/lockd/lockd.h
include/linux/lockd/lockd.h
+1
-1
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+54
-11
include/linux/nfs_idmap.h
include/linux/nfs_idmap.h
+2
-0
include/linux/nfs_page.h
include/linux/nfs_page.h
+3
-9
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+47
-42
include/linux/sunrpc/clnt.h
include/linux/sunrpc/clnt.h
+3
-2
include/linux/sunrpc/gss_spkm3.h
include/linux/sunrpc/gss_spkm3.h
+1
-1
include/linux/sunrpc/sched.h
include/linux/sunrpc/sched.h
+37
-11
include/linux/sunrpc/xdr.h
include/linux/sunrpc/xdr.h
+0
-6
include/linux/sunrpc/xprt.h
include/linux/sunrpc/xprt.h
+7
-5
include/linux/writeback.h
include/linux/writeback.h
+5
-4
mm/page-writeback.c
mm/page-writeback.c
+8
-2
net/sunrpc/auth_gss/gss_krb5_mech.c
net/sunrpc/auth_gss/gss_krb5_mech.c
+7
-3
net/sunrpc/auth_gss/gss_spkm3_mech.c
net/sunrpc/auth_gss/gss_spkm3_mech.c
+7
-3
net/sunrpc/auth_gss/gss_spkm3_seal.c
net/sunrpc/auth_gss/gss_spkm3_seal.c
+5
-6
net/sunrpc/auth_gss/gss_spkm3_token.c
net/sunrpc/auth_gss/gss_spkm3_token.c
+2
-1
net/sunrpc/auth_gss/gss_spkm3_unseal.c
net/sunrpc/auth_gss/gss_spkm3_unseal.c
+1
-1
net/sunrpc/clnt.c
net/sunrpc/clnt.c
+60
-47
net/sunrpc/pmap_clnt.c
net/sunrpc/pmap_clnt.c
+8
-9
net/sunrpc/rpc_pipe.c
net/sunrpc/rpc_pipe.c
+6
-3
net/sunrpc/sched.c
net/sunrpc/sched.c
+135
-87
net/sunrpc/sunrpc_syms.c
net/sunrpc/sunrpc_syms.c
+0
-4
net/sunrpc/xdr.c
net/sunrpc/xdr.c
+0
-21
net/sunrpc/xprt.c
net/sunrpc/xprt.c
+25
-41
net/sunrpc/xprtsock.c
net/sunrpc/xprtsock.c
+29
-2
未找到文件。
Documentation/kernel-parameters.txt
浏览文件 @
47853e7f
...
...
@@ -910,6 +910,14 @@ running once the system is up.
nfsroot= [NFS] nfs root filesystem for disk-less boxes.
See Documentation/nfsroot.txt.
nfs.callback_tcpport=
[NFS] set the TCP port on which the NFSv4 callback
channel should listen.
nfs.idmap_cache_timeout=
[NFS] set the maximum lifetime for idmapper cache
entries.
nmi_watchdog= [KNL,BUGS=IA-32] Debugging features for SMP kernels
no387 [BUGS=IA-32] Tells the kernel to use the 387 maths
...
...
fs/lockd/clntproc.c
浏览文件 @
47853e7f
...
...
@@ -26,11 +26,12 @@
static
int
nlmclnt_test
(
struct
nlm_rqst
*
,
struct
file_lock
*
);
static
int
nlmclnt_lock
(
struct
nlm_rqst
*
,
struct
file_lock
*
);
static
int
nlmclnt_unlock
(
struct
nlm_rqst
*
,
struct
file_lock
*
);
static
void
nlmclnt_unlock_callback
(
struct
rpc_task
*
);
static
void
nlmclnt_cancel_callback
(
struct
rpc_task
*
);
static
int
nlm_stat_to_errno
(
u32
stat
);
static
void
nlmclnt_locks_init_private
(
struct
file_lock
*
fl
,
struct
nlm_host
*
host
);
static
const
struct
rpc_call_ops
nlmclnt_unlock_ops
;
static
const
struct
rpc_call_ops
nlmclnt_cancel_ops
;
/*
* Cookie counter for NLM requests
*/
...
...
@@ -222,7 +223,6 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
}
clnt
->
cl_softrtry
=
nfssrv
->
client
->
cl_softrtry
;
clnt
->
cl_intr
=
nfssrv
->
client
->
cl_intr
;
clnt
->
cl_chatty
=
nfssrv
->
client
->
cl_chatty
;
}
/* Keep the old signal mask */
...
...
@@ -399,8 +399,7 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
/*
* Generic NLM call, async version.
*/
int
nlmsvc_async_call
(
struct
nlm_rqst
*
req
,
u32
proc
,
rpc_action
callback
)
int
nlmsvc_async_call
(
struct
nlm_rqst
*
req
,
u32
proc
,
const
struct
rpc_call_ops
*
tk_ops
)
{
struct
nlm_host
*
host
=
req
->
a_host
;
struct
rpc_clnt
*
clnt
;
...
...
@@ -419,13 +418,12 @@ nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
msg
.
rpc_proc
=
&
clnt
->
cl_procinfo
[
proc
];
/* bootstrap and kick off the async RPC call */
status
=
rpc_call_async
(
clnt
,
&
msg
,
RPC_TASK_ASYNC
,
callback
,
req
);
status
=
rpc_call_async
(
clnt
,
&
msg
,
RPC_TASK_ASYNC
,
tk_ops
,
req
);
return
status
;
}
static
int
nlmclnt_async_call
(
struct
nlm_rqst
*
req
,
u32
proc
,
rpc_action
callback
)
static
int
nlmclnt_async_call
(
struct
nlm_rqst
*
req
,
u32
proc
,
const
struct
rpc_call_ops
*
tk_ops
)
{
struct
nlm_host
*
host
=
req
->
a_host
;
struct
rpc_clnt
*
clnt
;
...
...
@@ -448,7 +446,7 @@ nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
/* Increment host refcount */
nlm_get_host
(
host
);
/* bootstrap and kick off the async RPC call */
status
=
rpc_call_async
(
clnt
,
&
msg
,
RPC_TASK_ASYNC
,
callback
,
req
);
status
=
rpc_call_async
(
clnt
,
&
msg
,
RPC_TASK_ASYNC
,
tk_ops
,
req
);
if
(
status
<
0
)
nlm_release_host
(
host
);
return
status
;
...
...
@@ -664,7 +662,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
if
(
req
->
a_flags
&
RPC_TASK_ASYNC
)
{
status
=
nlmclnt_async_call
(
req
,
NLMPROC_UNLOCK
,
nlmclnt_unlock_callback
);
&
nlmclnt_unlock_ops
);
/* Hrmf... Do the unlock early since locks_remove_posix()
* really expects us to free the lock synchronously */
do_vfs_lock
(
fl
);
...
...
@@ -692,10 +690,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
return
-
ENOLCK
;
}
static
void
nlmclnt_unlock_callback
(
struct
rpc_task
*
task
)
static
void
nlmclnt_unlock_callback
(
struct
rpc_task
*
task
,
void
*
data
)
{
struct
nlm_rqst
*
req
=
(
struct
nlm_rqst
*
)
task
->
tk_call
data
;
struct
nlm_rqst
*
req
=
data
;
int
status
=
req
->
a_res
.
status
;
if
(
RPC_ASSASSINATED
(
task
))
...
...
@@ -722,6 +719,10 @@ nlmclnt_unlock_callback(struct rpc_task *task)
rpc_restart_call
(
task
);
}
static
const
struct
rpc_call_ops
nlmclnt_unlock_ops
=
{
.
rpc_call_done
=
nlmclnt_unlock_callback
,
};
/*
* Cancel a blocked lock request.
* We always use an async RPC call for this in order not to hang a
...
...
@@ -750,8 +751,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
nlmclnt_setlockargs
(
req
,
fl
);
status
=
nlmclnt_async_call
(
req
,
NLMPROC_CANCEL
,
nlmclnt_cancel_callback
);
status
=
nlmclnt_async_call
(
req
,
NLMPROC_CANCEL
,
&
nlmclnt_cancel_ops
);
if
(
status
<
0
)
{
nlmclnt_release_lockargs
(
req
);
kfree
(
req
);
...
...
@@ -765,10 +765,9 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
return
status
;
}
static
void
nlmclnt_cancel_callback
(
struct
rpc_task
*
task
)
static
void
nlmclnt_cancel_callback
(
struct
rpc_task
*
task
,
void
*
data
)
{
struct
nlm_rqst
*
req
=
(
struct
nlm_rqst
*
)
task
->
tk_call
data
;
struct
nlm_rqst
*
req
=
data
;
if
(
RPC_ASSASSINATED
(
task
))
goto
die
;
...
...
@@ -807,6 +806,10 @@ nlmclnt_cancel_callback(struct rpc_task *task)
rpc_delay
(
task
,
30
*
HZ
);
}
static
const
struct
rpc_call_ops
nlmclnt_cancel_ops
=
{
.
rpc_call_done
=
nlmclnt_cancel_callback
,
};
/*
* Convert an NLM status code to a generic kernel errno
*/
...
...
fs/lockd/host.c
浏览文件 @
47853e7f
...
...
@@ -177,7 +177,7 @@ nlm_bind_host(struct nlm_host *host)
if
((
clnt
=
host
->
h_rpcclnt
)
!=
NULL
)
{
xprt
=
clnt
->
cl_xprt
;
if
(
time_after_eq
(
jiffies
,
host
->
h_nextrebind
))
{
clnt
->
cl_port
=
0
;
rpc_force_rebind
(
clnt
)
;
host
->
h_nextrebind
=
jiffies
+
NLM_HOST_REBIND
;
dprintk
(
"lockd: next rebind in %ld jiffies
\n
"
,
host
->
h_nextrebind
-
jiffies
);
...
...
@@ -217,7 +217,7 @@ nlm_rebind_host(struct nlm_host *host)
{
dprintk
(
"lockd: rebind host %s
\n
"
,
host
->
h_name
);
if
(
host
->
h_rpcclnt
&&
time_after_eq
(
jiffies
,
host
->
h_nextrebind
))
{
host
->
h_rpcclnt
->
cl_port
=
0
;
rpc_force_rebind
(
host
->
h_rpcclnt
)
;
host
->
h_nextrebind
=
jiffies
+
NLM_HOST_REBIND
;
}
}
...
...
fs/lockd/mon.c
浏览文件 @
47853e7f
...
...
@@ -123,7 +123,6 @@ nsm_create(void)
if
(
IS_ERR
(
clnt
))
goto
out_err
;
clnt
->
cl_softrtry
=
1
;
clnt
->
cl_chatty
=
1
;
clnt
->
cl_oneshot
=
1
;
return
clnt
;
...
...
fs/lockd/svc.c
浏览文件 @
47853e7f
...
...
@@ -178,6 +178,8 @@ lockd(struct svc_rqst *rqstp)
}
flush_signals
(
current
);
/*
* Check whether there's a new lockd process before
* shutting down the hosts and clearing the slot.
...
...
@@ -192,8 +194,6 @@ lockd(struct svc_rqst *rqstp)
"lockd: new process, skipping host shutdown
\n
"
);
wake_up
(
&
lockd_exit
);
flush_signals
(
current
);
/* Exit the RPC thread */
svc_exit_thread
(
rqstp
);
...
...
fs/lockd/svc4proc.c
浏览文件 @
47853e7f
...
...
@@ -22,7 +22,8 @@
#define NLMDBG_FACILITY NLMDBG_CLIENT
static
u32
nlm4svc_callback
(
struct
svc_rqst
*
,
u32
,
struct
nlm_res
*
);
static
void
nlm4svc_callback_exit
(
struct
rpc_task
*
);
static
const
struct
rpc_call_ops
nlm4svc_callback_ops
;
/*
* Obtain client and file from arguments
...
...
@@ -470,7 +471,6 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp,
}
/*
* This is the generic lockd callback for async RPC calls
*/
...
...
@@ -494,7 +494,7 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
call
->
a_host
=
host
;
memcpy
(
&
call
->
a_args
,
resp
,
sizeof
(
*
resp
));
if
(
nlmsvc_async_call
(
call
,
proc
,
nlm4svc_callback_exit
)
<
0
)
if
(
nlmsvc_async_call
(
call
,
proc
,
&
nlm4svc_callback_ops
)
<
0
)
goto
error
;
return
rpc_success
;
...
...
@@ -504,10 +504,9 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
return
rpc_system_err
;
}
static
void
nlm4svc_callback_exit
(
struct
rpc_task
*
task
)
static
void
nlm4svc_callback_exit
(
struct
rpc_task
*
task
,
void
*
data
)
{
struct
nlm_rqst
*
call
=
(
struct
nlm_rqst
*
)
task
->
tk_call
data
;
struct
nlm_rqst
*
call
=
data
;
if
(
task
->
tk_status
<
0
)
{
dprintk
(
"lockd: %4d callback failed (errno = %d)
\n
"
,
...
...
@@ -517,6 +516,10 @@ nlm4svc_callback_exit(struct rpc_task *task)
kfree
(
call
);
}
static
const
struct
rpc_call_ops
nlm4svc_callback_ops
=
{
.
rpc_call_done
=
nlm4svc_callback_exit
,
};
/*
* NLM Server procedures.
*/
...
...
fs/lockd/svclock.c
浏览文件 @
47853e7f
...
...
@@ -41,7 +41,8 @@
static
void
nlmsvc_insert_block
(
struct
nlm_block
*
block
,
unsigned
long
);
static
int
nlmsvc_remove_block
(
struct
nlm_block
*
block
);
static
void
nlmsvc_grant_callback
(
struct
rpc_task
*
task
);
static
const
struct
rpc_call_ops
nlmsvc_grant_ops
;
/*
* The list of blocked locks to retry
...
...
@@ -226,31 +227,27 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
* It is the caller's responsibility to check whether the file
* can be closed hereafter.
*/
static
void
static
int
nlmsvc_delete_block
(
struct
nlm_block
*
block
,
int
unlock
)
{
struct
file_lock
*
fl
=
&
block
->
b_call
.
a_args
.
lock
.
fl
;
struct
nlm_file
*
file
=
block
->
b_file
;
struct
nlm_block
**
bp
;
int
status
=
0
;
dprintk
(
"lockd: deleting block %p...
\n
"
,
block
);
/* Remove block from list */
nlmsvc_remove_block
(
block
);
if
(
fl
->
fl_next
)
posix_unblock_lock
(
file
->
f_file
,
fl
);
if
(
unlock
)
{
fl
->
fl_type
=
F_UNLCK
;
posix_lock_file
(
file
->
f_file
,
fl
);
block
->
b_granted
=
0
;
}
if
(
unlock
)
status
=
posix_unblock_lock
(
file
->
f_file
,
fl
);
/* If the block is in the middle of a GRANT callback,
* don't kill it yet. */
if
(
block
->
b_incall
)
{
nlmsvc_insert_block
(
block
,
NLM_NEVER
);
block
->
b_done
=
1
;
return
;
return
status
;
}
/* Remove block from file's list of blocks */
...
...
@@ -265,6 +262,7 @@ nlmsvc_delete_block(struct nlm_block *block, int unlock)
nlm_release_host
(
block
->
b_host
);
nlmclnt_freegrantargs
(
&
block
->
b_call
);
kfree
(
block
);
return
status
;
}
/*
...
...
@@ -275,6 +273,7 @@ int
nlmsvc_traverse_blocks
(
struct
nlm_host
*
host
,
struct
nlm_file
*
file
,
int
action
)
{
struct
nlm_block
*
block
,
*
next
;
/* XXX: Will everything get cleaned up if we don't unlock here? */
down
(
&
file
->
f_sema
);
for
(
block
=
file
->
f_blocks
;
block
;
block
=
next
)
{
...
...
@@ -444,6 +443,7 @@ u32
nlmsvc_cancel_blocked
(
struct
nlm_file
*
file
,
struct
nlm_lock
*
lock
)
{
struct
nlm_block
*
block
;
int
status
=
0
;
dprintk
(
"lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)
\n
"
,
file
->
f_file
->
f_dentry
->
d_inode
->
i_sb
->
s_id
,
...
...
@@ -454,9 +454,9 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
down
(
&
file
->
f_sema
);
if
((
block
=
nlmsvc_lookup_block
(
file
,
lock
,
1
))
!=
NULL
)
nlmsvc_delete_block
(
block
,
1
);
status
=
nlmsvc_delete_block
(
block
,
1
);
up
(
&
file
->
f_sema
);
return
nlm_granted
;
return
status
?
nlm_lck_denied
:
nlm_granted
;
}
/*
...
...
@@ -562,7 +562,7 @@ nlmsvc_grant_blocked(struct nlm_block *block)
/* Call the client */
nlm_get_host
(
block
->
b_call
.
a_host
);
if
(
nlmsvc_async_call
(
&
block
->
b_call
,
NLMPROC_GRANTED_MSG
,
nlmsvc_grant_callback
)
<
0
)
&
nlmsvc_grant_ops
)
<
0
)
nlm_release_host
(
block
->
b_call
.
a_host
);
up
(
&
file
->
f_sema
);
}
...
...
@@ -575,10 +575,9 @@ nlmsvc_grant_blocked(struct nlm_block *block)
* chain once more in order to have it removed by lockd itself (which can
* then sleep on the file semaphore without disrupting e.g. the nfs client).
*/
static
void
nlmsvc_grant_callback
(
struct
rpc_task
*
task
)
static
void
nlmsvc_grant_callback
(
struct
rpc_task
*
task
,
void
*
data
)
{
struct
nlm_rqst
*
call
=
(
struct
nlm_rqst
*
)
task
->
tk_call
data
;
struct
nlm_rqst
*
call
=
data
;
struct
nlm_block
*
block
;
unsigned
long
timeout
;
struct
sockaddr_in
*
peer_addr
=
RPC_PEERADDR
(
task
->
tk_client
);
...
...
@@ -614,6 +613,10 @@ nlmsvc_grant_callback(struct rpc_task *task)
nlm_release_host
(
call
->
a_host
);
}
static
const
struct
rpc_call_ops
nlmsvc_grant_ops
=
{
.
rpc_call_done
=
nlmsvc_grant_callback
,
};
/*
* We received a GRANT_RES callback. Try to find the corresponding
* block.
...
...
@@ -633,11 +636,12 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status
file
->
f_count
++
;
down
(
&
file
->
f_sema
);
if
((
block
=
nlmsvc_find_block
(
cookie
,
&
rqstp
->
rq_addr
))
!=
NULL
)
{
block
=
nlmsvc_find_block
(
cookie
,
&
rqstp
->
rq_addr
);
if
(
block
)
{
if
(
status
==
NLM_LCK_DENIED_GRACE_PERIOD
)
{
/* Try again in a couple of seconds */
nlmsvc_insert_block
(
block
,
10
*
HZ
);
block
=
NULL
;
up
(
&
file
->
f_sema
)
;
}
else
{
/* Lock is now held by client, or has been rejected.
* In both cases, the block should be removed. */
...
...
@@ -648,8 +652,6 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status
nlmsvc_delete_block
(
block
,
1
);
}
}
if
(
!
block
)
up
(
&
file
->
f_sema
);
nlm_release_file
(
file
);
}
...
...
fs/lockd/svcproc.c
浏览文件 @
47853e7f
...
...
@@ -23,7 +23,8 @@
#define NLMDBG_FACILITY NLMDBG_CLIENT
static
u32
nlmsvc_callback
(
struct
svc_rqst
*
,
u32
,
struct
nlm_res
*
);
static
void
nlmsvc_callback_exit
(
struct
rpc_task
*
);
static
const
struct
rpc_call_ops
nlmsvc_callback_ops
;
#ifdef CONFIG_LOCKD_V4
static
u32
...
...
@@ -518,7 +519,7 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
call
->
a_host
=
host
;
memcpy
(
&
call
->
a_args
,
resp
,
sizeof
(
*
resp
));
if
(
nlmsvc_async_call
(
call
,
proc
,
nlmsvc_callback_exit
)
<
0
)
if
(
nlmsvc_async_call
(
call
,
proc
,
&
nlmsvc_callback_ops
)
<
0
)
goto
error
;
return
rpc_success
;
...
...
@@ -528,10 +529,9 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
return
rpc_system_err
;
}
static
void
nlmsvc_callback_exit
(
struct
rpc_task
*
task
)
static
void
nlmsvc_callback_exit
(
struct
rpc_task
*
task
,
void
*
data
)
{
struct
nlm_rqst
*
call
=
(
struct
nlm_rqst
*
)
task
->
tk_call
data
;
struct
nlm_rqst
*
call
=
data
;
if
(
task
->
tk_status
<
0
)
{
dprintk
(
"lockd: %4d callback failed (errno = %d)
\n
"
,
...
...
@@ -541,6 +541,10 @@ nlmsvc_callback_exit(struct rpc_task *task)
kfree
(
call
);
}
static
const
struct
rpc_call_ops
nlmsvc_callback_ops
=
{
.
rpc_call_done
=
nlmsvc_callback_exit
,
};
/*
* NLM Server procedures.
*/
...
...
fs/lockd/xdr4.c
浏览文件 @
47853e7f
...
...
@@ -355,6 +355,8 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp)
argp
->
state
=
ntohl
(
*
p
++
);
/* Preserve the address in network byte order */
argp
->
addr
=
*
p
++
;
argp
->
vers
=
*
p
++
;
argp
->
proto
=
*
p
++
;
return
xdr_argsize_check
(
rqstp
,
p
);
}
...
...
fs/locks.c
浏览文件 @
47853e7f
...
...
@@ -1958,22 +1958,18 @@ EXPORT_SYMBOL(posix_block_lock);
*
* lockd needs to block waiting for locks.
*/
void
int
posix_unblock_lock
(
struct
file
*
filp
,
struct
file_lock
*
waiter
)
{
/*
* A remote machine may cancel the lock request after it's been
* granted locally. If that happens, we need to delete the lock.
*/
int
status
=
0
;
lock_kernel
();
if
(
waiter
->
fl_next
)
{
if
(
waiter
->
fl_next
)
__locks_delete_block
(
waiter
);
else
status
=
-
ENOENT
;
unlock_kernel
();
}
else
{
unlock_kernel
();
waiter
->
fl_type
=
F_UNLCK
;
posix_lock_file
(
filp
,
waiter
);
}
return
status
;
}
EXPORT_SYMBOL
(
posix_unblock_lock
);
...
...
fs/nfs/Makefile
浏览文件 @
47853e7f
...
...
@@ -13,4 +13,5 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
delegation.o idmap.o
\
callback.o callback_xdr.o callback_proc.o
nfs-$(CONFIG_NFS_DIRECTIO)
+=
direct.o
nfs-$(CONFIG_SYSCTL)
+=
sysctl.o
nfs-objs
:=
$
(
nfs-y
)
fs/nfs/callback.c
浏览文件 @
47853e7f
...
...
@@ -34,6 +34,7 @@ static struct nfs_callback_data nfs_callback_info;
static
DECLARE_MUTEX
(
nfs_callback_sema
);
static
struct
svc_program
nfs4_callback_program
;
unsigned
int
nfs_callback_set_tcpport
;
unsigned
short
nfs_callback_tcpport
;
/*
...
...
@@ -98,7 +99,7 @@ int nfs_callback_up(void)
if
(
!
serv
)
goto
out_err
;
/* FIXME: We don't want to register this socket with the portmapper */
ret
=
svc_makesock
(
serv
,
IPPROTO_TCP
,
0
);
ret
=
svc_makesock
(
serv
,
IPPROTO_TCP
,
nfs_callback_set_tcpport
);
if
(
ret
<
0
)
goto
out_destroy
;
if
(
!
list_empty
(
&
serv
->
sv_permsocks
))
{
...
...
fs/nfs/callback.h
浏览文件 @
47853e7f
...
...
@@ -65,6 +65,7 @@ extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
extern
int
nfs_callback_up
(
void
);
extern
int
nfs_callback_down
(
void
);
extern
unsigned
int
nfs_callback_set_tcpport
;
extern
unsigned
short
nfs_callback_tcpport
;
#endif
/* __LINUX_FS_NFS_CALLBACK_H */
fs/nfs/callback_proc.c
浏览文件 @
47853e7f
...
...
@@ -35,7 +35,9 @@ unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres
if
(
delegation
==
NULL
||
(
delegation
->
type
&
FMODE_WRITE
)
==
0
)
goto
out_iput
;
res
->
size
=
i_size_read
(
inode
);
res
->
change_attr
=
NFS_CHANGE_ATTR
(
inode
);
res
->
change_attr
=
delegation
->
change_attr
;
if
(
nfsi
->
npages
!=
0
)
res
->
change_attr
++
;
res
->
ctime
=
inode
->
i_ctime
;
res
->
mtime
=
inode
->
i_mtime
;
res
->
bitmap
[
0
]
=
(
FATTR4_WORD0_CHANGE
|
FATTR4_WORD0_SIZE
)
&
...
...
fs/nfs/delegation.c
浏览文件 @
47853e7f
...
...
@@ -8,6 +8,7 @@
*/
#include <linux/config.h>
#include <linux/completion.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
...
...
@@ -130,6 +131,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
sizeof
(
delegation
->
stateid
.
data
));
delegation
->
type
=
res
->
delegation_type
;
delegation
->
maxsize
=
res
->
maxsize
;
delegation
->
change_attr
=
nfsi
->
change_attr
;
delegation
->
cred
=
get_rpccred
(
cred
);
delegation
->
inode
=
inode
;
...
...
@@ -157,8 +159,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
{
int
res
=
0
;
__nfs_revalidate_inode
(
NFS_SERVER
(
inode
),
inode
);
res
=
nfs4_proc_delegreturn
(
inode
,
delegation
->
cred
,
&
delegation
->
stateid
);
nfs_free_delegation
(
delegation
);
return
res
;
...
...
@@ -231,6 +231,49 @@ void nfs_return_all_delegations(struct super_block *sb)
spin_unlock
(
&
clp
->
cl_lock
);
}
int
nfs_do_expire_all_delegations
(
void
*
ptr
)
{
struct
nfs4_client
*
clp
=
ptr
;
struct
nfs_delegation
*
delegation
;
struct
inode
*
inode
;
allow_signal
(
SIGKILL
);
restart:
spin_lock
(
&
clp
->
cl_lock
);
if
(
test_bit
(
NFS4CLNT_STATE_RECOVER
,
&
clp
->
cl_state
)
!=
0
)
goto
out
;
if
(
test_bit
(
NFS4CLNT_LEASE_EXPIRED
,
&
clp
->
cl_state
)
==
0
)
goto
out
;
list_for_each_entry
(
delegation
,
&
clp
->
cl_delegations
,
super_list
)
{
inode
=
igrab
(
delegation
->
inode
);
if
(
inode
==
NULL
)
continue
;
spin_unlock
(
&
clp
->
cl_lock
);
nfs_inode_return_delegation
(
inode
);
iput
(
inode
);
goto
restart
;
}
out:
spin_unlock
(
&
clp
->
cl_lock
);
nfs4_put_client
(
clp
);
module_put_and_exit
(
0
);
}
void
nfs_expire_all_delegations
(
struct
nfs4_client
*
clp
)
{
struct
task_struct
*
task
;
__module_get
(
THIS_MODULE
);
atomic_inc
(
&
clp
->
cl_count
);
task
=
kthread_run
(
nfs_do_expire_all_delegations
,
clp
,
"%u.%u.%u.%u-delegreturn"
,
NIPQUAD
(
clp
->
cl_addr
));
if
(
!
IS_ERR
(
task
))
return
;
nfs4_put_client
(
clp
);
module_put
(
THIS_MODULE
);
}
/*
* Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
*/
...
...
fs/nfs/delegation.h
浏览文件 @
47853e7f
...
...
@@ -21,6 +21,7 @@ struct nfs_delegation {
#define NFS_DELEGATION_NEED_RECLAIM 1
long
flags
;
loff_t
maxsize
;
__u64
change_attr
;
};
int
nfs_inode_set_delegation
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
struct
nfs_openres
*
res
);
...
...
@@ -30,6 +31,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
struct
inode
*
nfs_delegation_find_inode
(
struct
nfs4_client
*
clp
,
const
struct
nfs_fh
*
fhandle
);
void
nfs_return_all_delegations
(
struct
super_block
*
sb
);
void
nfs_expire_all_delegations
(
struct
nfs4_client
*
clp
);
void
nfs_handle_cb_pathdown
(
struct
nfs4_client
*
clp
);
void
nfs_delegation_mark_reclaim
(
struct
nfs4_client
*
clp
);
...
...
fs/nfs/dir.c
浏览文件 @
47853e7f
...
...
@@ -1550,8 +1550,10 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
}
nfs_inode_return_delegation
(
old_inode
);
if
(
new_inode
)
if
(
new_inode
!=
NULL
)
{
nfs_inode_return_delegation
(
new_inode
);
d_delete
(
new_dentry
);
}
nfs_begin_data_update
(
old_dir
);
nfs_begin_data_update
(
new_dir
);
...
...
fs/nfs/direct.c
浏览文件 @
47853e7f
...
...
@@ -122,9 +122,10 @@ nfs_free_user_pages(struct page **pages, int npages, int do_dirty)
{
int
i
;
for
(
i
=
0
;
i
<
npages
;
i
++
)
{
if
(
do_dirty
)
set_page_dirty_lock
(
pages
[
i
]);
page_cache_release
(
pages
[
i
]);
struct
page
*
page
=
pages
[
i
];
if
(
do_dirty
&&
!
PageCompound
(
page
))
set_page_dirty_lock
(
page
);
page_cache_release
(
page
);
}
kfree
(
pages
);
}
...
...
@@ -154,6 +155,7 @@ static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int
struct
list_head
*
list
;
struct
nfs_direct_req
*
dreq
;
unsigned
int
reads
=
0
;
unsigned
int
rpages
=
(
rsize
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
;
dreq
=
kmem_cache_alloc
(
nfs_direct_cachep
,
SLAB_KERNEL
);
if
(
!
dreq
)
...
...
@@ -167,7 +169,7 @@ static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int
list
=
&
dreq
->
list
;
for
(;;)
{
struct
nfs_read_data
*
data
=
nfs_readdata_alloc
();
struct
nfs_read_data
*
data
=
nfs_readdata_alloc
(
rpages
);
if
(
unlikely
(
!
data
))
{
while
(
!
list_empty
(
list
))
{
...
...
@@ -268,8 +270,6 @@ static void nfs_direct_read_schedule(struct nfs_direct_req *dreq,
NFS_PROTO
(
inode
)
->
read_setup
(
data
);
data
->
task
.
tk_cookie
=
(
unsigned
long
)
inode
;
data
->
task
.
tk_calldata
=
data
;
data
->
task
.
tk_release
=
nfs_readdata_release
;
data
->
complete
=
nfs_direct_read_result
;
lock_kernel
();
...
...
@@ -433,7 +433,7 @@ static ssize_t nfs_direct_write_seg(struct inode *inode,
struct
nfs_writeverf
first_verf
;
struct
nfs_write_data
*
wdata
;
wdata
=
nfs_writedata_alloc
();
wdata
=
nfs_writedata_alloc
(
NFS_SERVER
(
inode
)
->
wpages
);
if
(
!
wdata
)
return
-
ENOMEM
;
...
...
@@ -662,10 +662,10 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t
.
iov_len
=
count
,
};
dprintk
(
"nfs: direct read(%s/%s, %lu@%
lu
)
\n
"
,
dprintk
(
"nfs: direct read(%s/%s, %lu@%
Ld
)
\n
"
,
file
->
f_dentry
->
d_parent
->
d_name
.
name
,
file
->
f_dentry
->
d_name
.
name
,
(
unsigned
long
)
count
,
(
unsigned
long
)
pos
);
(
unsigned
long
)
count
,
(
long
long
)
pos
);
if
(
!
is_sync_kiocb
(
iocb
))
goto
out
;
...
...
@@ -718,9 +718,7 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t
ssize_t
nfs_file_direct_write
(
struct
kiocb
*
iocb
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
ssize_t
retval
=
-
EINVAL
;
loff_t
*
ppos
=
&
iocb
->
ki_pos
;
unsigned
long
limit
=
current
->
signal
->
rlim
[
RLIMIT_FSIZE
].
rlim_cur
;
ssize_t
retval
;
struct
file
*
file
=
iocb
->
ki_filp
;
struct
nfs_open_context
*
ctx
=
(
struct
nfs_open_context
*
)
file
->
private_data
;
...
...
@@ -728,35 +726,32 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
struct
inode
*
inode
=
mapping
->
host
;
struct
iovec
iov
=
{
.
iov_base
=
(
char
__user
*
)
buf
,
.
iov_len
=
count
,
};
dfprintk
(
VFS
,
"nfs: direct write(%s/%s
(%ld), %lu@%lu
)
\n
"
,
dfprintk
(
VFS
,
"nfs: direct write(%s/%s
, %lu@%Ld
)
\n
"
,
file
->
f_dentry
->
d_parent
->
d_name
.
name
,
file
->
f_dentry
->
d_name
.
name
,
inode
->
i_ino
,
(
unsigned
long
)
count
,
(
unsigned
long
)
pos
);
file
->
f_dentry
->
d_name
.
name
,
(
unsigned
long
)
count
,
(
long
long
)
pos
);
retval
=
-
EINVAL
;
if
(
!
is_sync_kiocb
(
iocb
))
goto
out
;
if
(
count
<
0
)
goto
out
;
if
(
pos
<
0
)
goto
out
;
retval
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_READ
,
iov
.
iov_base
,
iov
.
iov_len
))
retval
=
generic_write_checks
(
file
,
&
pos
,
&
count
,
0
);
if
(
retval
)
goto
out
;
retval
=
-
EFBIG
;
if
(
limit
!=
RLIM_INFINITY
)
{
if
(
pos
>=
limit
)
{
send_sig
(
SIGXFSZ
,
current
,
0
);
retval
=
-
EINVAL
;
if
((
ssize_t
)
count
<
0
)
goto
out
;
}
if
(
count
>
limit
-
(
unsigned
long
)
pos
)
count
=
limit
-
(
unsigned
long
)
pos
;
}
retval
=
0
;
if
(
!
count
)
goto
out
;
iov
.
iov_len
=
count
,
retval
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_READ
,
iov
.
iov_base
,
iov
.
iov_len
))
goto
out
;
retval
=
nfs_sync_mapping
(
mapping
);
if
(
retval
)
...
...
@@ -766,7 +761,7 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
if
(
mapping
->
nrpages
)
invalidate_inode_pages2
(
mapping
);
if
(
retval
>
0
)
*
p
pos
=
pos
+
retval
;
iocb
->
ki_
pos
=
pos
+
retval
;
out:
return
retval
;
...
...
fs/nfs/idmap.c
浏览文件 @
47853e7f
...
...
@@ -54,7 +54,11 @@
#define IDMAP_HASH_SZ 128
/* Default cache timeout is 10 minutes */
unsigned
int
nfs_idmap_cache_timeout
=
600
*
HZ
;
struct
idmap_hashent
{
unsigned
long
ih_expires
;
__u32
ih_id
;
int
ih_namelen
;
char
ih_name
[
IDMAP_NAMESZ
];
...
...
@@ -149,6 +153,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
if
(
he
->
ih_namelen
!=
len
||
memcmp
(
he
->
ih_name
,
name
,
len
)
!=
0
)
return
NULL
;
if
(
time_after
(
jiffies
,
he
->
ih_expires
))
return
NULL
;
return
he
;
}
...
...
@@ -164,6 +170,8 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
struct
idmap_hashent
*
he
=
idmap_id_hash
(
h
,
id
);
if
(
he
->
ih_id
!=
id
||
he
->
ih_namelen
==
0
)
return
NULL
;
if
(
time_after
(
jiffies
,
he
->
ih_expires
))
return
NULL
;
return
he
;
}
...
...
@@ -192,6 +200,7 @@ idmap_update_entry(struct idmap_hashent *he, const char *name,
memcpy
(
he
->
ih_name
,
name
,
namelen
);
he
->
ih_name
[
namelen
]
=
'\0'
;
he
->
ih_namelen
=
namelen
;
he
->
ih_expires
=
jiffies
+
nfs_idmap_cache_timeout
;
}
/*
...
...
fs/nfs/inode.c
浏览文件 @
47853e7f
...
...
@@ -40,6 +40,7 @@
#include <asm/uaccess.h>
#include "nfs4_fs.h"
#include "callback.h"
#include "delegation.h"
#define NFSDBG_FACILITY NFSDBG_VFS
...
...
@@ -221,10 +222,10 @@ nfs_calc_block_size(u64 tsize)
static
inline
unsigned
long
nfs_block_size
(
unsigned
long
bsize
,
unsigned
char
*
nrbitsp
)
{
if
(
bsize
<
1024
)
bsize
=
NFS_DEF_FILE_IO_
BUFFER_
SIZE
;
else
if
(
bsize
>=
NFS_MAX_FILE_IO_
BUFFER_
SIZE
)
bsize
=
NFS_MAX_FILE_IO_
BUFFER_
SIZE
;
if
(
bsize
<
NFS_MIN_FILE_IO_SIZE
)
bsize
=
NFS_DEF_FILE_IO_SIZE
;
else
if
(
bsize
>=
NFS_MAX_FILE_IO_SIZE
)
bsize
=
NFS_MAX_FILE_IO_SIZE
;
return
nfs_block_bits
(
bsize
,
nrbitsp
);
}
...
...
@@ -307,20 +308,15 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
max_rpc_payload
=
nfs_block_size
(
rpc_max_payload
(
server
->
client
),
NULL
);
if
(
server
->
rsize
>
max_rpc_payload
)
server
->
rsize
=
max_rpc_payload
;
if
(
server
->
wsize
>
max_rpc_payload
)
server
->
wsize
=
max_rpc_payload
;
if
(
server
->
rsize
>
NFS_MAX_FILE_IO_SIZE
)
server
->
rsize
=
NFS_MAX_FILE_IO_SIZE
;
server
->
rpages
=
(
server
->
rsize
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
;
if
(
server
->
rpages
>
NFS_READ_MAXIOV
)
{
server
->
rpages
=
NFS_READ_MAXIOV
;
server
->
rsize
=
server
->
rpages
<<
PAGE_CACHE_SHIFT
;
}
if
(
server
->
wsize
>
max_rpc_payload
)
server
->
wsize
=
max_rpc_payload
;
if
(
server
->
wsize
>
NFS_MAX_FILE_IO_SIZE
)
server
->
wsize
=
NFS_MAX_FILE_IO_SIZE
;
server
->
wpages
=
(
server
->
wsize
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
;
if
(
server
->
wpages
>
NFS_WRITE_MAXIOV
)
{
server
->
wpages
=
NFS_WRITE_MAXIOV
;
server
->
wsize
=
server
->
wpages
<<
PAGE_CACHE_SHIFT
;
}
if
(
sb
->
s_blocksize
==
0
)
sb
->
s_blocksize
=
nfs_block_bits
(
server
->
wsize
,
...
...
@@ -417,7 +413,6 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
clnt
->
cl_intr
=
1
;
clnt
->
cl_softrtry
=
1
;
clnt
->
cl_chatty
=
1
;
return
clnt
;
...
...
@@ -575,11 +570,10 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf)
buf
->
f_namelen
=
server
->
namelen
;
out:
unlock_kernel
();
return
0
;
out_err:
printk
(
KERN_WARNING
"nfs_statfs: statfs error = %d
\n
"
,
-
error
);
dprintk
(
"%s: statfs error = %d
\n
"
,
__FUNCTION__
,
-
error
);
buf
->
f_bsize
=
buf
->
f_blocks
=
buf
->
f_bfree
=
buf
->
f_bavail
=
-
1
;
goto
out
;
...
...
@@ -958,6 +952,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
int
need_atime
=
NFS_I
(
inode
)
->
cache_validity
&
NFS_INO_INVALID_ATIME
;
int
err
;
/* Flush out writes to the server in order to update c/mtime */
nfs_sync_inode
(
inode
,
0
,
0
,
FLUSH_WAIT
|
FLUSH_NOCOMMIT
);
if
(
__IS_FLG
(
inode
,
MS_NOATIME
))
need_atime
=
0
;
else
if
(
__IS_FLG
(
inode
,
MS_NODIRATIME
)
&&
S_ISDIR
(
inode
->
i_mode
))
...
...
@@ -1252,6 +1248,33 @@ void nfs_end_data_update(struct inode *inode)
atomic_dec
(
&
nfsi
->
data_updates
);
}
static
void
nfs_wcc_update_inode
(
struct
inode
*
inode
,
struct
nfs_fattr
*
fattr
)
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
if
((
fattr
->
valid
&
NFS_ATTR_PRE_CHANGE
)
!=
0
&&
nfsi
->
change_attr
==
fattr
->
pre_change_attr
)
{
nfsi
->
change_attr
=
fattr
->
change_attr
;
nfsi
->
cache_change_attribute
=
jiffies
;
}
/* If we have atomic WCC data, we may update some attributes */
if
((
fattr
->
valid
&
NFS_ATTR_WCC
)
!=
0
)
{
if
(
timespec_equal
(
&
inode
->
i_ctime
,
&
fattr
->
pre_ctime
))
{
memcpy
(
&
inode
->
i_ctime
,
&
fattr
->
ctime
,
sizeof
(
inode
->
i_ctime
));
nfsi
->
cache_change_attribute
=
jiffies
;
}
if
(
timespec_equal
(
&
inode
->
i_mtime
,
&
fattr
->
pre_mtime
))
{
memcpy
(
&
inode
->
i_mtime
,
&
fattr
->
mtime
,
sizeof
(
inode
->
i_mtime
));
nfsi
->
cache_change_attribute
=
jiffies
;
}
if
(
inode
->
i_size
==
fattr
->
pre_size
&&
nfsi
->
npages
==
0
)
{
inode
->
i_size
=
fattr
->
size
;
nfsi
->
cache_change_attribute
=
jiffies
;
}
}
}
/**
* nfs_check_inode_attributes - verify consistency of the inode attribute cache
* @inode - pointer to inode
...
...
@@ -1268,23 +1291,21 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
int
data_unstable
;
if
((
fattr
->
valid
&
NFS_ATTR_FATTR
)
==
0
)
return
0
;
/* Are we in the process of updating data on the server? */
data_unstable
=
nfs_caches_unstable
(
inode
);
if
(
fattr
->
valid
&
NFS_ATTR_FATTR_V4
)
{
if
((
fattr
->
valid
&
NFS_ATTR_PRE_CHANGE
)
!=
0
&&
nfsi
->
change_attr
==
fattr
->
pre_change_attr
)
nfsi
->
change_attr
=
fattr
->
change_attr
;
if
(
nfsi
->
change_attr
!=
fattr
->
change_attr
)
{
/* Do atomic weak cache consistency updates */
nfs_wcc_update_inode
(
inode
,
fattr
);
if
((
fattr
->
valid
&
NFS_ATTR_FATTR_V4
)
!=
0
&&
nfsi
->
change_attr
!=
fattr
->
change_attr
)
{
nfsi
->
cache_validity
|=
NFS_INO_INVALID_ATTR
;
if
(
!
data_unstable
)
nfsi
->
cache_validity
|=
NFS_INO_REVAL_PAGECACHE
;
}
}
if
((
fattr
->
valid
&
NFS_ATTR_FATTR
)
==
0
)
{
return
0
;
}
/* Has the inode gone and changed behind our back? */
if
(
nfsi
->
fileid
!=
fattr
->
fileid
...
...
@@ -1295,14 +1316,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
cur_size
=
i_size_read
(
inode
);
new_isize
=
nfs_size_to_loff_t
(
fattr
->
size
);
/* If we have atomic WCC data, we may update some attributes */
if
((
fattr
->
valid
&
NFS_ATTR_WCC
)
!=
0
)
{
if
(
timespec_equal
(
&
inode
->
i_ctime
,
&
fattr
->
pre_ctime
))
memcpy
(
&
inode
->
i_ctime
,
&
fattr
->
ctime
,
sizeof
(
inode
->
i_ctime
));
if
(
timespec_equal
(
&
inode
->
i_mtime
,
&
fattr
->
pre_mtime
))
memcpy
(
&
inode
->
i_mtime
,
&
fattr
->
mtime
,
sizeof
(
inode
->
i_mtime
));
}
/* Verify a few of the more important attributes */
if
(
!
timespec_equal
(
&
inode
->
i_mtime
,
&
fattr
->
mtime
))
{
nfsi
->
cache_validity
|=
NFS_INO_INVALID_ATTR
;
...
...
@@ -1410,14 +1423,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if
((
fattr
->
valid
&
NFS_ATTR_FATTR
)
==
0
)
return
0
;
if
(
nfsi
->
fileid
!=
fattr
->
fileid
)
{
printk
(
KERN_ERR
"%s: inode number mismatch
\n
"
"expected (%s/0x%Lx), got (%s/0x%Lx)
\n
"
,
__FUNCTION__
,
inode
->
i_sb
->
s_id
,
(
long
long
)
nfsi
->
fileid
,
inode
->
i_sb
->
s_id
,
(
long
long
)
fattr
->
fileid
);
goto
out_err
;
}
if
(
nfsi
->
fileid
!=
fattr
->
fileid
)
goto
out_fileid
;
/*
* Make sure the inode's type hasn't changed.
...
...
@@ -1436,6 +1443,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if
(
data_stable
)
nfsi
->
cache_validity
&=
~
(
NFS_INO_INVALID_ATTR
|
NFS_INO_INVALID_ATIME
);
/* Do atomic weak cache consistency updates */
nfs_wcc_update_inode
(
inode
,
fattr
);
/* Check if our cached file size is stale */
new_isize
=
nfs_size_to_loff_t
(
fattr
->
size
);
cur_isize
=
i_size_read
(
inode
);
...
...
@@ -1539,6 +1549,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
*/
nfs_invalidate_inode
(
inode
);
return
-
ESTALE
;
out_fileid:
printk
(
KERN_ERR
"NFS: server %s error: fileid changed
\n
"
"fsid %s: expected fileid 0x%Lx, got 0x%Lx
\n
"
,
NFS_SERVER
(
inode
)
->
hostname
,
inode
->
i_sb
->
s_id
,
(
long
long
)
nfsi
->
fileid
,
(
long
long
)
fattr
->
fileid
);
goto
out_err
;
}
/*
...
...
@@ -1820,25 +1837,10 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
}
clnt
->
cl_intr
=
1
;
clnt
->
cl_softrtry
=
1
;
clnt
->
cl_chatty
=
1
;
clp
->
cl_rpcclient
=
clnt
;
clp
->
cl_cred
=
rpcauth_lookupcred
(
clnt
->
cl_auth
,
0
);
if
(
IS_ERR
(
clp
->
cl_cred
))
{
up_write
(
&
clp
->
cl_sem
);
err
=
PTR_ERR
(
clp
->
cl_cred
);
clp
->
cl_cred
=
NULL
;
goto
out_fail
;
}
memcpy
(
clp
->
cl_ipaddr
,
server
->
ip_addr
,
sizeof
(
clp
->
cl_ipaddr
));
nfs_idmap_new
(
clp
);
}
if
(
list_empty
(
&
clp
->
cl_superblocks
))
{
err
=
nfs4_init_client
(
clp
);
if
(
err
!=
0
)
{
up_write
(
&
clp
->
cl_sem
);
goto
out_fail
;
}
}
list_add_tail
(
&
server
->
nfs4_siblings
,
&
clp
->
cl_superblocks
);
clnt
=
rpc_clone_client
(
clp
->
cl_rpcclient
);
if
(
!
IS_ERR
(
clnt
))
...
...
@@ -2033,6 +2035,35 @@ static struct file_system_type nfs4_fs_type = {
.
fs_flags
=
FS_ODD_RENAME
|
FS_REVAL_DOT
|
FS_BINARY_MOUNTDATA
,
};
static
const
int
nfs_set_port_min
=
0
;
static
const
int
nfs_set_port_max
=
65535
;
static
int
param_set_port
(
const
char
*
val
,
struct
kernel_param
*
kp
)
{
char
*
endp
;
int
num
=
simple_strtol
(
val
,
&
endp
,
0
);
if
(
endp
==
val
||
*
endp
||
num
<
nfs_set_port_min
||
num
>
nfs_set_port_max
)
return
-
EINVAL
;
*
((
int
*
)
kp
->
arg
)
=
num
;
return
0
;
}
module_param_call
(
callback_tcpport
,
param_set_port
,
param_get_int
,
&
nfs_callback_set_tcpport
,
0644
);
static
int
param_set_idmap_timeout
(
const
char
*
val
,
struct
kernel_param
*
kp
)
{
char
*
endp
;
int
num
=
simple_strtol
(
val
,
&
endp
,
0
);
int
jif
=
num
*
HZ
;
if
(
endp
==
val
||
*
endp
||
num
<
0
||
jif
<
num
)
return
-
EINVAL
;
*
((
int
*
)
kp
->
arg
)
=
jif
;
return
0
;
}
module_param_call
(
idmap_cache_timeout
,
param_set_idmap_timeout
,
param_get_int
,
&
nfs_idmap_cache_timeout
,
0644
);
#define nfs4_init_once(nfsi) \
do { \
INIT_LIST_HEAD(&(nfsi)->open_states); \
...
...
@@ -2040,8 +2071,25 @@ static struct file_system_type nfs4_fs_type = {
nfsi->delegation_state = 0; \
init_rwsem(&nfsi->rwsem); \
} while(0)
#define register_nfs4fs() register_filesystem(&nfs4_fs_type)
#define unregister_nfs4fs() unregister_filesystem(&nfs4_fs_type)
static
inline
int
register_nfs4fs
(
void
)
{
int
ret
;
ret
=
nfs_register_sysctl
();
if
(
ret
!=
0
)
return
ret
;
ret
=
register_filesystem
(
&
nfs4_fs_type
);
if
(
ret
!=
0
)
nfs_unregister_sysctl
();
return
ret
;
}
static
inline
void
unregister_nfs4fs
(
void
)
{
unregister_filesystem
(
&
nfs4_fs_type
);
nfs_unregister_sysctl
();
}
#else
#define nfs4_init_once(nfsi) \
do { } while (0)
...
...
@@ -2166,11 +2214,11 @@ static int __init init_nfs_fs(void)
#ifdef CONFIG_PROC_FS
rpc_proc_unregister
(
"nfs"
);
#endif
nfs_destroy_writepagecache
();
#ifdef CONFIG_NFS_DIRECTIO
out0:
nfs_destroy_directcache
();
out0:
#endif
nfs_destroy_writepagecache
();
out1:
nfs_destroy_readpagecache
();
out2:
...
...
fs/nfs/mount_clnt.c
浏览文件 @
47853e7f
...
...
@@ -82,7 +82,6 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
RPC_AUTH_UNIX
);
if
(
!
IS_ERR
(
clnt
))
{
clnt
->
cl_softrtry
=
1
;
clnt
->
cl_chatty
=
1
;
clnt
->
cl_oneshot
=
1
;
clnt
->
cl_intr
=
1
;
}
...
...
fs/nfs/nfs2xdr.c
浏览文件 @
47853e7f
...
...
@@ -146,23 +146,23 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
return
p
;
}
#define SATTR(p, attr, flag, field) \
*p++ = (attr->ia_valid & flag) ? htonl(attr->field) : ~(u32) 0
static
inline
u32
*
xdr_encode_sattr
(
u32
*
p
,
struct
iattr
*
attr
)
{
SATTR
(
p
,
attr
,
ATTR_MODE
,
ia_mode
);
SATTR
(
p
,
attr
,
ATTR_UID
,
ia_uid
);
SATTR
(
p
,
attr
,
ATTR_GID
,
ia_gid
);
SATTR
(
p
,
attr
,
ATTR_SIZE
,
ia_size
);
const
u32
not_set
=
__constant_htonl
(
0xFFFFFFFF
);
*
p
++
=
(
attr
->
ia_valid
&
ATTR_MODE
)
?
htonl
(
attr
->
ia_mode
)
:
not_set
;
*
p
++
=
(
attr
->
ia_valid
&
ATTR_UID
)
?
htonl
(
attr
->
ia_uid
)
:
not_set
;
*
p
++
=
(
attr
->
ia_valid
&
ATTR_GID
)
?
htonl
(
attr
->
ia_gid
)
:
not_set
;
*
p
++
=
(
attr
->
ia_valid
&
ATTR_SIZE
)
?
htonl
(
attr
->
ia_size
)
:
not_set
;
if
(
attr
->
ia_valid
&
ATTR_ATIME_SET
)
{
p
=
xdr_encode_time
(
p
,
&
attr
->
ia_atime
);
}
else
if
(
attr
->
ia_valid
&
ATTR_ATIME
)
{
p
=
xdr_encode_current_server_time
(
p
,
&
attr
->
ia_atime
);
}
else
{
*
p
++
=
~
(
u32
)
0
;
*
p
++
=
~
(
u32
)
0
;
*
p
++
=
not_set
;
*
p
++
=
not_set
;
}
if
(
attr
->
ia_valid
&
ATTR_MTIME_SET
)
{
...
...
@@ -170,12 +170,11 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
}
else
if
(
attr
->
ia_valid
&
ATTR_MTIME
)
{
p
=
xdr_encode_current_server_time
(
p
,
&
attr
->
ia_mtime
);
}
else
{
*
p
++
=
~
(
u32
)
0
;
*
p
++
=
~
(
u32
)
0
;
*
p
++
=
not_set
;
*
p
++
=
not_set
;
}
return
p
;
}
#undef SATTR
/*
* NFS encode functions
...
...
fs/nfs/nfs3proc.c
浏览文件 @
47853e7f
...
...
@@ -68,26 +68,38 @@ nfs3_async_handle_jukebox(struct rpc_task *task)
return
1
;
}
/*
* Bare-bones access to getattr: this is for nfs_read_super.
*/
static
int
nfs3_proc_get_root
(
struct
nfs_server
*
server
,
struct
nfs_fh
*
fhandle
,
do_proc_get_root
(
struct
rpc_clnt
*
client
,
struct
nfs_fh
*
fhandle
,
struct
nfs_fsinfo
*
info
)
{
int
status
;
dprintk
(
"%s: call fsinfo
\n
"
,
__FUNCTION__
);
nfs_fattr_init
(
info
->
fattr
);
status
=
rpc_call
(
server
->
client_sys
,
NFS3PROC_FSINFO
,
fhandle
,
info
,
0
);
status
=
rpc_call
(
client
,
NFS3PROC_FSINFO
,
fhandle
,
info
,
0
);
dprintk
(
"%s: reply fsinfo: %d
\n
"
,
__FUNCTION__
,
status
);
if
(
!
(
info
->
fattr
->
valid
&
NFS_ATTR_FATTR
))
{
status
=
rpc_call
(
server
->
client_sys
,
NFS3PROC_GETATTR
,
fhandle
,
info
->
fattr
,
0
);
status
=
rpc_call
(
client
,
NFS3PROC_GETATTR
,
fhandle
,
info
->
fattr
,
0
);
dprintk
(
"%s: reply getattr: %d
\n
"
,
__FUNCTION__
,
status
);
}
return
status
;
}
/*
* Bare-bones access to getattr: this is for nfs_read_super.
*/
static
int
nfs3_proc_get_root
(
struct
nfs_server
*
server
,
struct
nfs_fh
*
fhandle
,
struct
nfs_fsinfo
*
info
)
{
int
status
;
status
=
do_proc_get_root
(
server
->
client
,
fhandle
,
info
);
if
(
status
&&
server
->
client_sys
!=
server
->
client
)
status
=
do_proc_get_root
(
server
->
client_sys
,
fhandle
,
info
);
return
status
;
}
/*
* One function for each procedure in the NFS protocol.
*/
...
...
@@ -732,19 +744,23 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
extern
u32
*
nfs3_decode_dirent
(
u32
*
,
struct
nfs_entry
*
,
int
);
static
void
nfs3_read_done
(
struct
rpc_task
*
task
)
static
void
nfs3_read_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_read_data
*
data
=
(
struct
nfs_read_data
*
)
task
->
tk_
calldata
;
struct
nfs_read_data
*
data
=
calldata
;
if
(
nfs3_async_handle_jukebox
(
task
))
return
;
/* Call back common NFS readpage processing */
if
(
task
->
tk_status
>=
0
)
nfs_refresh_inode
(
data
->
inode
,
&
data
->
fattr
);
nfs_readpage_result
(
task
);
nfs_readpage_result
(
task
,
calldata
);
}
static
const
struct
rpc_call_ops
nfs3_read_ops
=
{
.
rpc_call_done
=
nfs3_read_done
,
.
rpc_release
=
nfs_readdata_release
,
};
static
void
nfs3_proc_read_setup
(
struct
nfs_read_data
*
data
)
{
...
...
@@ -762,23 +778,26 @@ nfs3_proc_read_setup(struct nfs_read_data *data)
flags
=
RPC_TASK_ASYNC
|
(
IS_SWAPFILE
(
inode
)
?
NFS_RPC_SWAPFLAGS
:
0
);
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_read_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
flags
,
&
nfs3_read_ops
,
data
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
static
void
nfs3_write_done
(
struct
rpc_task
*
task
)
static
void
nfs3_write_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_write_data
*
data
;
struct
nfs_write_data
*
data
=
calldata
;
if
(
nfs3_async_handle_jukebox
(
task
))
return
;
data
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
if
(
task
->
tk_status
>=
0
)
nfs_post_op_update_inode
(
data
->
inode
,
data
->
res
.
fattr
);
nfs_writeback_done
(
task
);
nfs_writeback_done
(
task
,
calldata
);
}
static
const
struct
rpc_call_ops
nfs3_write_ops
=
{
.
rpc_call_done
=
nfs3_write_done
,
.
rpc_release
=
nfs_writedata_release
,
};
static
void
nfs3_proc_write_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
...
...
@@ -806,23 +825,26 @@ nfs3_proc_write_setup(struct nfs_write_data *data, int how)
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_write_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
flags
,
&
nfs3_write_ops
,
data
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
static
void
nfs3_commit_done
(
struct
rpc_task
*
task
)
static
void
nfs3_commit_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_write_data
*
data
;
struct
nfs_write_data
*
data
=
calldata
;
if
(
nfs3_async_handle_jukebox
(
task
))
return
;
data
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
if
(
task
->
tk_status
>=
0
)
nfs_post_op_update_inode
(
data
->
inode
,
data
->
res
.
fattr
);
nfs_commit_done
(
task
);
nfs_commit_done
(
task
,
calldata
);
}
static
const
struct
rpc_call_ops
nfs3_commit_ops
=
{
.
rpc_call_done
=
nfs3_commit_done
,
.
rpc_release
=
nfs_commit_release
,
};
static
void
nfs3_proc_commit_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
...
...
@@ -840,7 +862,7 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_commit_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
flags
,
&
nfs3_commit_ops
,
data
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
...
...
fs/nfs/nfs3xdr.c
浏览文件 @
47853e7f
...
...
@@ -182,7 +182,7 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
{
if
(
attr
->
ia_valid
&
ATTR_MODE
)
{
*
p
++
=
xdr_one
;
*
p
++
=
htonl
(
attr
->
ia_mode
);
*
p
++
=
htonl
(
attr
->
ia_mode
&
S_IALLUGO
);
}
else
{
*
p
++
=
xdr_zero
;
}
...
...
fs/nfs/nfs4_fs.h
浏览文件 @
47853e7f
...
...
@@ -38,7 +38,8 @@ struct idmap;
((err) != NFSERR_NOFILEHANDLE))
enum
nfs4_client_state
{
NFS4CLNT_OK
=
0
,
NFS4CLNT_STATE_RECOVER
=
0
,
NFS4CLNT_LEASE_EXPIRED
,
};
/*
...
...
@@ -67,7 +68,6 @@ struct nfs4_client {
atomic_t
cl_count
;
struct
rpc_clnt
*
cl_rpcclient
;
struct
rpc_cred
*
cl_cred
;
struct
list_head
cl_superblocks
;
/* List of nfs_server structs */
...
...
@@ -76,7 +76,6 @@ struct nfs4_client {
struct
work_struct
cl_renewd
;
struct
work_struct
cl_recoverd
;
wait_queue_head_t
cl_waitq
;
struct
rpc_wait_queue
cl_rpcwaitq
;
/* used for the setclientid verifier */
...
...
@@ -182,8 +181,9 @@ struct nfs4_state {
nfs4_stateid
stateid
;
unsigned
int
nreaders
;
unsigned
int
nwriters
;
unsigned
int
n_rdonly
;
unsigned
int
n_wronly
;
unsigned
int
n_rdwr
;
int
state
;
/* State on the server (R,W, or RW) */
atomic_t
count
;
};
...
...
@@ -210,10 +210,10 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
/* nfs4proc.c */
extern
int
nfs4_map_errors
(
int
err
);
extern
int
nfs4_proc_setclientid
(
struct
nfs4_client
*
,
u32
,
unsigned
short
);
extern
int
nfs4_proc_setclientid_confirm
(
struct
nfs4_client
*
);
extern
int
nfs4_proc_async_renew
(
struct
nfs4_client
*
);
extern
int
nfs4_proc_renew
(
struct
nfs4_client
*
);
extern
int
nfs4_proc_setclientid
(
struct
nfs4_client
*
,
u32
,
unsigned
short
,
struct
rpc_cred
*
);
extern
int
nfs4_proc_setclientid_confirm
(
struct
nfs4_client
*
,
struct
rpc_cred
*
);
extern
int
nfs4_proc_async_renew
(
struct
nfs4_client
*
,
struct
rpc_cred
*
);
extern
int
nfs4_proc_renew
(
struct
nfs4_client
*
,
struct
rpc_cred
*
);
extern
int
nfs4_do_close
(
struct
inode
*
inode
,
struct
nfs4_state
*
state
);
extern
struct
dentry
*
nfs4_atomic_open
(
struct
inode
*
,
struct
dentry
*
,
struct
nameidata
*
);
extern
int
nfs4_open_revalidate
(
struct
inode
*
,
struct
dentry
*
,
int
,
struct
nameidata
*
);
...
...
@@ -237,8 +237,8 @@ extern void init_nfsv4_state(struct nfs_server *);
extern
void
destroy_nfsv4_state
(
struct
nfs_server
*
);
extern
struct
nfs4_client
*
nfs4_get_client
(
struct
in_addr
*
);
extern
void
nfs4_put_client
(
struct
nfs4_client
*
clp
);
extern
int
nfs4_init_client
(
struct
nfs4_client
*
clp
);
extern
struct
nfs4_client
*
nfs4_find_client
(
struct
in_addr
*
);
struct
rpc_cred
*
nfs4_get_renew_cred
(
struct
nfs4_client
*
clp
);
extern
u32
nfs4_alloc_lockowner_id
(
struct
nfs4_client
*
);
extern
struct
nfs4_state_owner
*
nfs4_get_state_owner
(
struct
nfs_server
*
,
struct
rpc_cred
*
);
...
...
fs/nfs/nfs4proc.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
fs/nfs/nfs4renewd.c
浏览文件 @
47853e7f
...
...
@@ -54,6 +54,7 @@
#include <linux/nfs4.h>
#include <linux/nfs_fs.h>
#include "nfs4_fs.h"
#include "delegation.h"
#define NFSDBG_FACILITY NFSDBG_PROC
...
...
@@ -61,6 +62,7 @@ void
nfs4_renew_state
(
void
*
data
)
{
struct
nfs4_client
*
clp
=
(
struct
nfs4_client
*
)
data
;
struct
rpc_cred
*
cred
;
long
lease
,
timeout
;
unsigned
long
last
,
now
;
...
...
@@ -76,9 +78,17 @@ nfs4_renew_state(void *data)
timeout
=
(
2
*
lease
)
/
3
+
(
long
)
last
-
(
long
)
now
;
/* Are we close to a lease timeout? */
if
(
time_after
(
now
,
last
+
lease
/
3
))
{
cred
=
nfs4_get_renew_cred
(
clp
);
if
(
cred
==
NULL
)
{
set_bit
(
NFS4CLNT_LEASE_EXPIRED
,
&
clp
->
cl_state
);
spin_unlock
(
&
clp
->
cl_lock
);
nfs_expire_all_delegations
(
clp
);
goto
out
;
}
spin_unlock
(
&
clp
->
cl_lock
);
/* Queue an asynchronous RENEW. */
nfs4_proc_async_renew
(
clp
);
nfs4_proc_async_renew
(
clp
,
cred
);
put_rpccred
(
cred
);
timeout
=
(
2
*
lease
)
/
3
;
spin_lock
(
&
clp
->
cl_lock
);
}
else
...
...
fs/nfs/nfs4state.c
浏览文件 @
47853e7f
...
...
@@ -43,6 +43,8 @@
#include <linux/smp_lock.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_idmap.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
...
...
@@ -57,8 +59,6 @@ const nfs4_stateid zero_stateid;
static
DEFINE_SPINLOCK
(
state_spinlock
);
static
LIST_HEAD
(
nfs4_clientid_list
);
static
void
nfs4_recover_state
(
void
*
);
void
init_nfsv4_state
(
struct
nfs_server
*
server
)
{
...
...
@@ -91,11 +91,10 @@ nfs4_alloc_client(struct in_addr *addr)
if
(
nfs_callback_up
()
<
0
)
return
NULL
;
if
((
clp
=
k
m
alloc
(
sizeof
(
*
clp
),
GFP_KERNEL
))
==
NULL
)
{
if
((
clp
=
k
z
alloc
(
sizeof
(
*
clp
),
GFP_KERNEL
))
==
NULL
)
{
nfs_callback_down
();
return
NULL
;
}
memset
(
clp
,
0
,
sizeof
(
*
clp
));
memcpy
(
&
clp
->
cl_addr
,
addr
,
sizeof
(
clp
->
cl_addr
));
init_rwsem
(
&
clp
->
cl_sem
);
INIT_LIST_HEAD
(
&
clp
->
cl_delegations
);
...
...
@@ -103,14 +102,12 @@ nfs4_alloc_client(struct in_addr *addr)
INIT_LIST_HEAD
(
&
clp
->
cl_unused
);
spin_lock_init
(
&
clp
->
cl_lock
);
atomic_set
(
&
clp
->
cl_count
,
1
);
INIT_WORK
(
&
clp
->
cl_recoverd
,
nfs4_recover_state
,
clp
);
INIT_WORK
(
&
clp
->
cl_renewd
,
nfs4_renew_state
,
clp
);
INIT_LIST_HEAD
(
&
clp
->
cl_superblocks
);
init_waitqueue_head
(
&
clp
->
cl_waitq
);
rpc_init_wait_queue
(
&
clp
->
cl_rpcwaitq
,
"NFS4 client"
);
clp
->
cl_rpcclient
=
ERR_PTR
(
-
EINVAL
);
clp
->
cl_boot_time
=
CURRENT_TIME
;
clp
->
cl_state
=
1
<<
NFS4CLNT_
OK
;
clp
->
cl_state
=
1
<<
NFS4CLNT_
LEASE_EXPIRED
;
return
clp
;
}
...
...
@@ -127,8 +124,6 @@ nfs4_free_client(struct nfs4_client *clp)
kfree
(
sp
);
}
BUG_ON
(
!
list_empty
(
&
clp
->
cl_state_owners
));
if
(
clp
->
cl_cred
)
put_rpccred
(
clp
->
cl_cred
);
nfs_idmap_delete
(
clp
);
if
(
!
IS_ERR
(
clp
->
cl_rpcclient
))
rpc_shutdown_client
(
clp
->
cl_rpcclient
);
...
...
@@ -193,27 +188,22 @@ nfs4_put_client(struct nfs4_client *clp)
list_del
(
&
clp
->
cl_servers
);
spin_unlock
(
&
state_spinlock
);
BUG_ON
(
!
list_empty
(
&
clp
->
cl_superblocks
));
wake_up_all
(
&
clp
->
cl_waitq
);
rpc_wake_up
(
&
clp
->
cl_rpcwaitq
);
nfs4_kill_renewd
(
clp
);
nfs4_free_client
(
clp
);
}
static
int
__nfs4_init_client
(
struct
nfs4_client
*
clp
)
static
int
nfs4_init_client
(
struct
nfs4_client
*
clp
,
struct
rpc_cred
*
cred
)
{
int
status
=
nfs4_proc_setclientid
(
clp
,
NFS4_CALLBACK
,
nfs_callback_tcpport
);
int
status
=
nfs4_proc_setclientid
(
clp
,
NFS4_CALLBACK
,
nfs_callback_tcpport
,
cred
);
if
(
status
==
0
)
status
=
nfs4_proc_setclientid_confirm
(
clp
);
status
=
nfs4_proc_setclientid_confirm
(
clp
,
cred
);
if
(
status
==
0
)
nfs4_schedule_state_renewal
(
clp
);
return
status
;
}
int
nfs4_init_client
(
struct
nfs4_client
*
clp
)
{
return
nfs4_map_errors
(
__nfs4_init_client
(
clp
));
}
u32
nfs4_alloc_lockowner_id
(
struct
nfs4_client
*
clp
)
{
...
...
@@ -235,6 +225,32 @@ nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred)
return
sp
;
}
struct
rpc_cred
*
nfs4_get_renew_cred
(
struct
nfs4_client
*
clp
)
{
struct
nfs4_state_owner
*
sp
;
struct
rpc_cred
*
cred
=
NULL
;
list_for_each_entry
(
sp
,
&
clp
->
cl_state_owners
,
so_list
)
{
if
(
list_empty
(
&
sp
->
so_states
))
continue
;
cred
=
get_rpccred
(
sp
->
so_cred
);
break
;
}
return
cred
;
}
struct
rpc_cred
*
nfs4_get_setclientid_cred
(
struct
nfs4_client
*
clp
)
{
struct
nfs4_state_owner
*
sp
;
if
(
!
list_empty
(
&
clp
->
cl_state_owners
))
{
sp
=
list_entry
(
clp
->
cl_state_owners
.
next
,
struct
nfs4_state_owner
,
so_list
);
return
get_rpccred
(
sp
->
so_cred
);
}
return
NULL
;
}
static
struct
nfs4_state_owner
*
nfs4_find_state_owner
(
struct
nfs4_client
*
clp
,
struct
rpc_cred
*
cred
)
{
...
...
@@ -349,14 +365,9 @@ nfs4_alloc_open_state(void)
{
struct
nfs4_state
*
state
;
state
=
k
m
alloc
(
sizeof
(
*
state
),
GFP_KERNEL
);
state
=
k
z
alloc
(
sizeof
(
*
state
),
GFP_KERNEL
);
if
(
!
state
)
return
NULL
;
state
->
state
=
0
;
state
->
nreaders
=
0
;
state
->
nwriters
=
0
;
state
->
flags
=
0
;
memset
(
state
->
stateid
.
data
,
0
,
sizeof
(
state
->
stateid
.
data
));
atomic_set
(
&
state
->
count
,
1
);
INIT_LIST_HEAD
(
&
state
->
lock_states
);
spin_lock_init
(
&
state
->
state_lock
);
...
...
@@ -475,15 +486,23 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
/* Protect against nfs4_find_state() */
spin_lock
(
&
owner
->
so_lock
);
spin_lock
(
&
inode
->
i_lock
);
if
(
mode
&
FMODE_READ
)
state
->
nreaders
--
;
if
(
mode
&
FMODE_WRITE
)
state
->
nwriters
--
;
switch
(
mode
&
(
FMODE_READ
|
FMODE_WRITE
))
{
case
FMODE_READ
:
state
->
n_rdonly
--
;
break
;
case
FMODE_WRITE
:
state
->
n_wronly
--
;
break
;
case
FMODE_READ
|
FMODE_WRITE
:
state
->
n_rdwr
--
;
}
oldstate
=
newstate
=
state
->
state
;
if
(
state
->
nreaders
==
0
)
if
(
state
->
n_rdwr
==
0
)
{
if
(
state
->
n_rdonly
==
0
)
newstate
&=
~
FMODE_READ
;
if
(
state
->
nwriters
==
0
)
if
(
state
->
n_wronly
==
0
)
newstate
&=
~
FMODE_WRITE
;
}
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
))
{
nfs4_state_set_mode_locked
(
state
,
newstate
);
oldstate
=
newstate
;
...
...
@@ -733,45 +752,43 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
}
static
int
reclaimer
(
void
*
);
struct
reclaimer_args
{
struct
nfs4_client
*
clp
;
struct
completion
complete
;
};
static
inline
void
nfs4_clear_recover_bit
(
struct
nfs4_client
*
clp
)
{
smp_mb__before_clear_bit
();
clear_bit
(
NFS4CLNT_STATE_RECOVER
,
&
clp
->
cl_state
);
smp_mb__after_clear_bit
();
wake_up_bit
(
&
clp
->
cl_state
,
NFS4CLNT_STATE_RECOVER
);
rpc_wake_up
(
&
clp
->
cl_rpcwaitq
);
}
/*
* State recovery routine
*/
void
nfs4_recover_state
(
void
*
data
)
static
void
nfs4_recover_state
(
struct
nfs4_client
*
clp
)
{
struct
nfs4_client
*
clp
=
(
struct
nfs4_client
*
)
data
;
struct
reclaimer_args
args
=
{
.
clp
=
clp
,
};
might_sleep
();
struct
task_struct
*
task
;
init_completion
(
&
args
.
complete
);
if
(
kernel_thread
(
reclaimer
,
&
args
,
CLONE_KERNEL
)
<
0
)
goto
out_failed_clear
;
wait_for_completion
(
&
args
.
complete
);
__module_get
(
THIS_MODULE
);
atomic_inc
(
&
clp
->
cl_count
);
task
=
kthread_run
(
reclaimer
,
clp
,
"%u.%u.%u.%u-reclaim"
,
NIPQUAD
(
clp
->
cl_addr
))
;
if
(
!
IS_ERR
(
task
))
return
;
out_failed_clear:
set_bit
(
NFS4CLNT_OK
,
&
clp
->
cl_state
);
wake_up_all
(
&
clp
->
cl_waitq
);
rpc_wake_up
(
&
clp
->
cl_rpcwaitq
);
nfs4_clear_recover_bit
(
clp
);
nfs4_put_client
(
clp
);
module_put
(
THIS_MODULE
);
}
/*
* Schedule a state recovery attempt
*/
void
nfs4_schedule_state_recovery
(
struct
nfs4_client
*
clp
)
void
nfs4_schedule_state_recovery
(
struct
nfs4_client
*
clp
)
{
if
(
!
clp
)
return
;
if
(
test_and_
clear_bit
(
NFS4CLNT_OK
,
&
clp
->
cl_state
)
)
schedule_work
(
&
clp
->
cl_recoverd
);
if
(
test_and_
set_bit
(
NFS4CLNT_STATE_RECOVER
,
&
clp
->
cl_state
)
==
0
)
nfs4_recover_state
(
clp
);
}
static
int
nfs4_reclaim_locks
(
struct
nfs4_state_recovery_ops
*
ops
,
struct
nfs4_state
*
state
)
...
...
@@ -887,18 +904,14 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp)
static
int
reclaimer
(
void
*
ptr
)
{
struct
reclaimer_args
*
args
=
(
struct
reclaimer_args
*
)
ptr
;
struct
nfs4_client
*
clp
=
args
->
clp
;
struct
nfs4_client
*
clp
=
ptr
;
struct
nfs4_state_owner
*
sp
;
struct
nfs4_state_recovery_ops
*
ops
;
struct
rpc_cred
*
cred
;
int
status
=
0
;
daemonize
(
"%u.%u.%u.%u-reclaim"
,
NIPQUAD
(
clp
->
cl_addr
));
allow_signal
(
SIGKILL
);
atomic_inc
(
&
clp
->
cl_count
);
complete
(
&
args
->
complete
);
/* Ensure exclusive access to NFSv4 state */
lock_kernel
();
down_write
(
&
clp
->
cl_sem
);
...
...
@@ -906,20 +919,33 @@ static int reclaimer(void *ptr)
if
(
list_empty
(
&
clp
->
cl_superblocks
))
goto
out
;
restart_loop:
status
=
nfs4_proc_renew
(
clp
);
ops
=
&
nfs4_network_partition_recovery_ops
;
/* Are there any open files on this volume? */
cred
=
nfs4_get_renew_cred
(
clp
);
if
(
cred
!=
NULL
)
{
/* Yes there are: try to renew the old lease */
status
=
nfs4_proc_renew
(
clp
,
cred
);
switch
(
status
)
{
case
0
:
case
-
NFS4ERR_CB_PATH_DOWN
:
put_rpccred
(
cred
);
goto
out
;
case
-
NFS4ERR_STALE_CLIENTID
:
case
-
NFS4ERR_LEASE_MOVED
:
ops
=
&
nfs4_reboot_recovery_ops
;
break
;
default:
ops
=
&
nfs4_network_partition_recovery_ops
;
};
}
}
else
{
/* "reboot" to ensure we clear all state on the server */
clp
->
cl_boot_time
=
CURRENT_TIME
;
cred
=
nfs4_get_setclientid_cred
(
clp
);
}
/* We're going to have to re-establish a clientid */
nfs4_state_mark_reclaim
(
clp
);
status
=
__nfs4_init_client
(
clp
);
status
=
-
ENOENT
;
if
(
cred
!=
NULL
)
{
status
=
nfs4_init_client
(
clp
,
cred
);
put_rpccred
(
cred
);
}
if
(
status
)
goto
out_error
;
/* Mark all delegations for reclaim */
...
...
@@ -940,14 +966,13 @@ static int reclaimer(void *ptr)
}
nfs_delegation_reap_unclaimed
(
clp
);
out:
set_bit
(
NFS4CLNT_OK
,
&
clp
->
cl_state
);
up_write
(
&
clp
->
cl_sem
);
unlock_kernel
();
wake_up_all
(
&
clp
->
cl_waitq
);
rpc_wake_up
(
&
clp
->
cl_rpcwaitq
);
if
(
status
==
-
NFS4ERR_CB_PATH_DOWN
)
nfs_handle_cb_pathdown
(
clp
);
nfs4_clear_recover_bit
(
clp
);
nfs4_put_client
(
clp
);
module_put_and_exit
(
0
);
return
0
;
out_error:
printk
(
KERN_WARNING
"Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d
\n
"
,
...
...
fs/nfs/nfs4xdr.c
浏览文件 @
47853e7f
...
...
@@ -392,9 +392,11 @@ static int nfs_stat_to_errno(int);
decode_getattr_maxsz)
#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_delegreturn_maxsz)
encode_delegreturn_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
decode_delegreturn_maxsz)
decode_delegreturn_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
...
...
@@ -564,7 +566,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
}
if
(
iap
->
ia_valid
&
ATTR_MODE
)
{
bmval1
|=
FATTR4_WORD1_MODE
;
WRITE32
(
iap
->
ia_mode
);
WRITE32
(
iap
->
ia_mode
&
S_IALLUGO
);
}
if
(
iap
->
ia_valid
&
ATTR_UID
)
{
bmval1
|=
FATTR4_WORD1_OWNER
;
...
...
@@ -742,69 +744,80 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
return
0
;
}
static
inline
int
nfs4_lock_type
(
struct
file_lock
*
fl
,
int
block
)
{
if
((
fl
->
fl_type
&
(
F_RDLCK
|
F_WRLCK
|
F_UNLCK
))
==
F_RDLCK
)
return
block
?
NFS4_READW_LT
:
NFS4_READ_LT
;
return
block
?
NFS4_WRITEW_LT
:
NFS4_WRITE_LT
;
}
static
inline
uint64_t
nfs4_lock_length
(
struct
file_lock
*
fl
)
{
if
(
fl
->
fl_end
==
OFFSET_MAX
)
return
~
(
uint64_t
)
0
;
return
fl
->
fl_end
-
fl
->
fl_start
+
1
;
}
/*
* opcode,type,reclaim,offset,length,new_lock_owner = 32
* open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
*/
static
int
encode_lock
(
struct
xdr_stream
*
xdr
,
const
struct
nfs_lock
args
*
arg
)
static
int
encode_lock
(
struct
xdr_stream
*
xdr
,
const
struct
nfs_lock
_args
*
args
)
{
uint32_t
*
p
;
struct
nfs_lock_opargs
*
opargs
=
arg
->
u
.
lock
;
RESERVE_SPACE
(
32
);
WRITE32
(
OP_LOCK
);
WRITE32
(
arg
->
type
);
WRITE32
(
op
args
->
reclaim
);
WRITE64
(
arg
->
offse
t
);
WRITE64
(
arg
->
length
);
WRITE32
(
op
args
->
new_lock_owner
);
if
(
op
args
->
new_lock_owner
){
WRITE32
(
nfs4_lock_type
(
args
->
fl
,
args
->
block
));
WRITE32
(
args
->
reclaim
);
WRITE64
(
arg
s
->
fl
->
fl_star
t
);
WRITE64
(
nfs4_lock_length
(
args
->
fl
)
);
WRITE32
(
args
->
new_lock_owner
);
if
(
args
->
new_lock_owner
){
RESERVE_SPACE
(
40
);
WRITE32
(
op
args
->
open_seqid
->
sequence
->
counter
);
WRITEMEM
(
opargs
->
open_stateid
->
data
,
sizeof
(
op
args
->
open_stateid
->
data
));
WRITE32
(
op
args
->
lock_seqid
->
sequence
->
counter
);
WRITE64
(
op
args
->
lock_owner
.
clientid
);
WRITE32
(
args
->
open_seqid
->
sequence
->
counter
);
WRITEMEM
(
args
->
open_stateid
->
data
,
sizeof
(
args
->
open_stateid
->
data
));
WRITE32
(
args
->
lock_seqid
->
sequence
->
counter
);
WRITE64
(
args
->
lock_owner
.
clientid
);
WRITE32
(
4
);
WRITE32
(
op
args
->
lock_owner
.
id
);
WRITE32
(
args
->
lock_owner
.
id
);
}
else
{
RESERVE_SPACE
(
20
);
WRITEMEM
(
opargs
->
lock_stateid
->
data
,
sizeof
(
op
args
->
lock_stateid
->
data
));
WRITE32
(
op
args
->
lock_seqid
->
sequence
->
counter
);
WRITEMEM
(
args
->
lock_stateid
->
data
,
sizeof
(
args
->
lock_stateid
->
data
));
WRITE32
(
args
->
lock_seqid
->
sequence
->
counter
);
}
return
0
;
}
static
int
encode_lockt
(
struct
xdr_stream
*
xdr
,
const
struct
nfs_lock
args
*
arg
)
static
int
encode_lockt
(
struct
xdr_stream
*
xdr
,
const
struct
nfs_lock
t_args
*
args
)
{
uint32_t
*
p
;
struct
nfs_lowner
*
opargs
=
arg
->
u
.
lockt
;
RESERVE_SPACE
(
40
);
WRITE32
(
OP_LOCKT
);
WRITE32
(
arg
->
type
);
WRITE64
(
arg
->
offse
t
);
WRITE64
(
arg
->
length
);
WRITE64
(
opargs
->
clientid
);
WRITE32
(
nfs4_lock_type
(
args
->
fl
,
0
)
);
WRITE64
(
arg
s
->
fl
->
fl_star
t
);
WRITE64
(
nfs4_lock_length
(
args
->
fl
)
);
WRITE64
(
args
->
lock_owner
.
clientid
);
WRITE32
(
4
);
WRITE32
(
opargs
->
id
);
WRITE32
(
args
->
lock_owner
.
id
);
return
0
;
}
static
int
encode_locku
(
struct
xdr_stream
*
xdr
,
const
struct
nfs_lock
args
*
arg
)
static
int
encode_locku
(
struct
xdr_stream
*
xdr
,
const
struct
nfs_lock
u_args
*
args
)
{
uint32_t
*
p
;
struct
nfs_locku_opargs
*
opargs
=
arg
->
u
.
locku
;
RESERVE_SPACE
(
44
);
WRITE32
(
OP_LOCKU
);
WRITE32
(
arg
->
type
);
WRITE32
(
op
args
->
seqid
->
sequence
->
counter
);
WRITEMEM
(
opargs
->
stateid
->
data
,
sizeof
(
op
args
->
stateid
->
data
));
WRITE64
(
arg
->
offse
t
);
WRITE64
(
arg
->
length
);
WRITE32
(
nfs4_lock_type
(
args
->
fl
,
0
)
);
WRITE32
(
args
->
seqid
->
sequence
->
counter
);
WRITEMEM
(
args
->
stateid
->
data
,
sizeof
(
args
->
stateid
->
data
));
WRITE64
(
arg
s
->
fl
->
fl_star
t
);
WRITE64
(
nfs4_lock_length
(
args
->
fl
)
);
return
0
;
}
...
...
@@ -964,9 +977,9 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
{
uint32_t
*
p
;
RESERVE_SPACE
(
8
+
sizeof
(
arg
->
stateid
.
data
));
RESERVE_SPACE
(
8
+
sizeof
(
arg
->
stateid
->
data
));
WRITE32
(
OP_OPEN_CONFIRM
);
WRITEMEM
(
arg
->
stateid
.
data
,
sizeof
(
arg
->
stateid
.
data
));
WRITEMEM
(
arg
->
stateid
->
data
,
sizeof
(
arg
->
stateid
->
data
));
WRITE32
(
arg
->
seqid
->
sequence
->
counter
);
return
0
;
...
...
@@ -1499,9 +1512,6 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena
};
int
status
;
status
=
nfs_wait_on_sequence
(
args
->
seqid
,
req
->
rq_task
);
if
(
status
!=
0
)
goto
out
;
xdr_init_encode
(
&
xdr
,
&
req
->
rq_snd_buf
,
p
);
encode_compound_hdr
(
&
xdr
,
&
hdr
);
status
=
encode_putfh
(
&
xdr
,
args
->
fh
);
...
...
@@ -1538,9 +1548,6 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
};
int
status
;
status
=
nfs_wait_on_sequence
(
args
->
seqid
,
req
->
rq_task
);
if
(
status
!=
0
)
goto
out
;
xdr_init_encode
(
&
xdr
,
&
req
->
rq_snd_buf
,
p
);
encode_compound_hdr
(
&
xdr
,
&
hdr
);
status
=
encode_putfh
(
&
xdr
,
args
->
fh
);
...
...
@@ -1558,19 +1565,19 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
=
{
.
nops
=
2
,
.
nops
=
3
,
};
int
status
;
status
=
nfs_wait_on_sequence
(
args
->
seqid
,
req
->
rq_task
);
if
(
status
!=
0
)
goto
out
;
xdr_init_encode
(
&
xdr
,
&
req
->
rq_snd_buf
,
p
);
encode_compound_hdr
(
&
xdr
,
&
hdr
);
status
=
encode_putfh
(
&
xdr
,
args
->
fh
);
if
(
status
)
goto
out
;
status
=
encode_open
(
&
xdr
,
args
);
if
(
status
)
goto
out
;
status
=
encode_getfattr
(
&
xdr
,
args
->
bitmask
);
out:
return
status
;
}
...
...
@@ -1602,21 +1609,14 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct
/*
* Encode a LOCK request
*/
static
int
nfs4_xdr_enc_lock
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_lockargs
*
args
)
static
int
nfs4_xdr_enc_lock
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_lock
_
args
*
args
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
=
{
.
nops
=
2
,
};
struct
nfs_lock_opargs
*
opargs
=
args
->
u
.
lock
;
int
status
;
status
=
nfs_wait_on_sequence
(
opargs
->
lock_seqid
,
req
->
rq_task
);
if
(
status
!=
0
)
goto
out
;
/* Do we need to do an open_to_lock_owner? */
if
(
opargs
->
lock_seqid
->
sequence
->
flags
&
NFS_SEQID_CONFIRMED
)
opargs
->
new_lock_owner
=
0
;
xdr_init_encode
(
&
xdr
,
&
req
->
rq_snd_buf
,
p
);
encode_compound_hdr
(
&
xdr
,
&
hdr
);
status
=
encode_putfh
(
&
xdr
,
args
->
fh
);
...
...
@@ -1630,7 +1630,7 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_locka
/*
* Encode a LOCKT request
*/
static
int
nfs4_xdr_enc_lockt
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_lockargs
*
args
)
static
int
nfs4_xdr_enc_lockt
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_lock
t_
args
*
args
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
=
{
...
...
@@ -1651,7 +1651,7 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lock
/*
* Encode a LOCKU request
*/
static
int
nfs4_xdr_enc_locku
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_lockargs
*
args
)
static
int
nfs4_xdr_enc_locku
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_lock
u_
args
*
args
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
=
{
...
...
@@ -1985,14 +1985,20 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const str
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
=
{
.
nops
=
2
,
.
nops
=
3
,
};
int
status
;
xdr_init_encode
(
&
xdr
,
&
req
->
rq_snd_buf
,
p
);
encode_compound_hdr
(
&
xdr
,
&
hdr
);
if
((
status
=
encode_putfh
(
&
xdr
,
args
->
fhandle
))
==
0
)
status
=
encode_putfh
(
&
xdr
,
args
->
fhandle
);
if
(
status
!=
0
)
goto
out
;
status
=
encode_delegreturn
(
&
xdr
,
args
->
stateid
);
if
(
status
!=
0
)
goto
out
;
status
=
encode_getfattr
(
&
xdr
,
args
->
bitmask
);
out:
return
status
;
}
...
...
@@ -2955,55 +2961,64 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
/*
* We create the owner, so we know a proper owner.id length is 4.
*/
static
int
decode_lock_denied
(
struct
xdr_stream
*
xdr
,
struct
nfs_lock_denied
*
denied
)
static
int
decode_lock_denied
(
struct
xdr_stream
*
xdr
,
struct
file_lock
*
fl
)
{
uint64_t
offset
,
length
,
clientid
;
uint32_t
*
p
;
uint32_t
namelen
;
uint32_t
namelen
,
type
;
READ_BUF
(
32
);
READ64
(
denied
->
offset
);
READ64
(
denied
->
length
);
READ32
(
denied
->
type
);
READ64
(
denied
->
owner
.
clientid
);
READ64
(
offset
);
READ64
(
length
);
READ32
(
type
);
if
(
fl
!=
NULL
)
{
fl
->
fl_start
=
(
loff_t
)
offset
;
fl
->
fl_end
=
fl
->
fl_start
+
(
loff_t
)
length
-
1
;
if
(
length
==
~
(
uint64_t
)
0
)
fl
->
fl_end
=
OFFSET_MAX
;
fl
->
fl_type
=
F_WRLCK
;
if
(
type
&
1
)
fl
->
fl_type
=
F_RDLCK
;
fl
->
fl_pid
=
0
;
}
READ64
(
clientid
);
READ32
(
namelen
);
READ_BUF
(
namelen
);
if
(
namelen
==
4
)
READ32
(
denied
->
owner
.
id
);
return
-
NFS4ERR_DENIED
;
}
static
int
decode_lock
(
struct
xdr_stream
*
xdr
,
struct
nfs_lockres
*
res
)
static
int
decode_lock
(
struct
xdr_stream
*
xdr
,
struct
nfs_lock
_
res
*
res
)
{
uint32_t
*
p
;
int
status
;
status
=
decode_op_hdr
(
xdr
,
OP_LOCK
);
if
(
status
==
0
)
{
READ_BUF
(
sizeof
(
res
->
u
.
stateid
.
data
));
COPYMEM
(
res
->
u
.
stateid
.
data
,
sizeof
(
res
->
u
.
stateid
.
data
));
READ_BUF
(
sizeof
(
res
->
stateid
.
data
));
COPYMEM
(
res
->
stateid
.
data
,
sizeof
(
res
->
stateid
.
data
));
}
else
if
(
status
==
-
NFS4ERR_DENIED
)
return
decode_lock_denied
(
xdr
,
&
res
->
u
.
denied
);
return
decode_lock_denied
(
xdr
,
NULL
);
return
status
;
}
static
int
decode_lockt
(
struct
xdr_stream
*
xdr
,
struct
nfs_lockres
*
res
)
static
int
decode_lockt
(
struct
xdr_stream
*
xdr
,
struct
nfs_lock
t_
res
*
res
)
{
int
status
;
status
=
decode_op_hdr
(
xdr
,
OP_LOCKT
);
if
(
status
==
-
NFS4ERR_DENIED
)
return
decode_lock_denied
(
xdr
,
&
res
->
u
.
denied
);
return
decode_lock_denied
(
xdr
,
res
->
denied
);
return
status
;
}
static
int
decode_locku
(
struct
xdr_stream
*
xdr
,
struct
nfs_lockres
*
res
)
static
int
decode_locku
(
struct
xdr_stream
*
xdr
,
struct
nfs_lock
u_
res
*
res
)
{
uint32_t
*
p
;
int
status
;
status
=
decode_op_hdr
(
xdr
,
OP_LOCKU
);
if
(
status
==
0
)
{
READ_BUF
(
sizeof
(
res
->
u
.
stateid
.
data
));
COPYMEM
(
res
->
u
.
stateid
.
data
,
sizeof
(
res
->
u
.
stateid
.
data
));
READ_BUF
(
sizeof
(
res
->
stateid
.
data
));
COPYMEM
(
res
->
stateid
.
data
,
sizeof
(
res
->
stateid
.
data
));
}
return
status
;
}
...
...
@@ -3831,6 +3846,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, uint32_t *p, struct
if
(
status
)
goto
out
;
status
=
decode_open
(
&
xdr
,
res
);
if
(
status
)
goto
out
;
decode_getfattr
(
&
xdr
,
res
->
f_attr
,
res
->
server
);
out:
return
status
;
}
...
...
@@ -3864,7 +3882,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_
/*
* Decode LOCK response
*/
static
int
nfs4_xdr_dec_lock
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_lockres
*
res
)
static
int
nfs4_xdr_dec_lock
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_lock
_
res
*
res
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
;
...
...
@@ -3885,7 +3903,7 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_loc
/*
* Decode LOCKT response
*/
static
int
nfs4_xdr_dec_lockt
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_lockres
*
res
)
static
int
nfs4_xdr_dec_lockt
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_lock
t_
res
*
res
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
;
...
...
@@ -3906,7 +3924,7 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lo
/*
* Decode LOCKU response
*/
static
int
nfs4_xdr_dec_locku
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_lockres
*
res
)
static
int
nfs4_xdr_dec_locku
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_lock
u_
res
*
res
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
;
...
...
@@ -4174,7 +4192,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s
/*
* DELEGRETURN request
*/
static
int
nfs4_xdr_dec_delegreturn
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
void
*
dummy
)
static
int
nfs4_xdr_dec_delegreturn
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs4_delegreturnres
*
res
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
;
...
...
@@ -4182,11 +4200,14 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d
xdr_init_decode
(
&
xdr
,
&
rqstp
->
rq_rcv_buf
,
p
);
status
=
decode_compound_hdr
(
&
xdr
,
&
hdr
);
if
(
status
==
0
)
{
if
(
status
!=
0
)
goto
out
;
status
=
decode_putfh
(
&
xdr
);
if
(
status
==
0
)
if
(
status
!=
0
)
goto
out
;
status
=
decode_delegreturn
(
&
xdr
);
}
decode_getfattr
(
&
xdr
,
res
->
fattr
,
res
->
server
);
out:
return
status
;
}
...
...
fs/nfs/nfsroot.c
浏览文件 @
47853e7f
...
...
@@ -296,8 +296,8 @@ static int __init root_nfs_name(char *name)
nfs_port
=
-
1
;
nfs_data
.
version
=
NFS_MOUNT_VERSION
;
nfs_data
.
flags
=
NFS_MOUNT_NONLM
;
/* No lockd in nfs root yet */
nfs_data
.
rsize
=
NFS_DEF_FILE_IO_
BUFFER_
SIZE
;
nfs_data
.
wsize
=
NFS_DEF_FILE_IO_
BUFFER_
SIZE
;
nfs_data
.
rsize
=
NFS_DEF_FILE_IO_SIZE
;
nfs_data
.
wsize
=
NFS_DEF_FILE_IO_SIZE
;
nfs_data
.
acregmin
=
3
;
nfs_data
.
acregmax
=
60
;
nfs_data
.
acdirmin
=
30
;
...
...
fs/nfs/proc.c
浏览文件 @
47853e7f
...
...
@@ -111,6 +111,9 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
};
int
status
;
/* Mask out the non-modebit related stuff from attr->ia_mode */
sattr
->
ia_mode
&=
S_IALLUGO
;
dprintk
(
"NFS call setattr
\n
"
);
nfs_fattr_init
(
fattr
);
status
=
rpc_call
(
NFS_CLIENT
(
inode
),
NFSPROC_SETATTR
,
&
arg
,
fattr
,
0
);
...
...
@@ -547,10 +550,9 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
extern
u32
*
nfs_decode_dirent
(
u32
*
,
struct
nfs_entry
*
,
int
);
static
void
nfs_read_done
(
struct
rpc_task
*
task
)
static
void
nfs_read_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_read_data
*
data
=
(
struct
nfs_read_data
*
)
task
->
tk_
calldata
;
struct
nfs_read_data
*
data
=
calldata
;
if
(
task
->
tk_status
>=
0
)
{
nfs_refresh_inode
(
data
->
inode
,
data
->
res
.
fattr
);
...
...
@@ -560,9 +562,14 @@ nfs_read_done(struct rpc_task *task)
if
(
data
->
args
.
offset
+
data
->
args
.
count
>=
data
->
res
.
fattr
->
size
)
data
->
res
.
eof
=
1
;
}
nfs_readpage_result
(
task
);
nfs_readpage_result
(
task
,
calldata
);
}
static
const
struct
rpc_call_ops
nfs_read_ops
=
{
.
rpc_call_done
=
nfs_read_done
,
.
rpc_release
=
nfs_readdata_release
,
};
static
void
nfs_proc_read_setup
(
struct
nfs_read_data
*
data
)
{
...
...
@@ -580,20 +587,24 @@ nfs_proc_read_setup(struct nfs_read_data *data)
flags
=
RPC_TASK_ASYNC
|
(
IS_SWAPFILE
(
inode
)
?
NFS_RPC_SWAPFLAGS
:
0
);
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs_read_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
flags
,
&
nfs_read_ops
,
data
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
static
void
nfs_write_done
(
struct
rpc_task
*
task
)
static
void
nfs_write_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_
calldata
;
struct
nfs_write_data
*
data
=
calldata
;
if
(
task
->
tk_status
>=
0
)
nfs_post_op_update_inode
(
data
->
inode
,
data
->
res
.
fattr
);
nfs_writeback_done
(
task
);
nfs_writeback_done
(
task
,
calldata
);
}
static
const
struct
rpc_call_ops
nfs_write_ops
=
{
.
rpc_call_done
=
nfs_write_done
,
.
rpc_release
=
nfs_writedata_release
,
};
static
void
nfs_proc_write_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
...
...
@@ -614,7 +625,7 @@ nfs_proc_write_setup(struct nfs_write_data *data, int how)
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs_write_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
flags
,
&
nfs_write_ops
,
data
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
...
...
fs/nfs/read.c
浏览文件 @
47853e7f
...
...
@@ -42,9 +42,8 @@ mempool_t *nfs_rdata_mempool;
#define MIN_POOL_READ (32)
void
nfs_readdata_release
(
struct
rpc_task
*
task
)
void
nfs_readdata_release
(
void
*
data
)
{
struct
nfs_read_data
*
data
=
(
struct
nfs_read_data
*
)
task
->
tk_calldata
;
nfs_readdata_free
(
data
);
}
...
...
@@ -84,7 +83,7 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
int
result
;
struct
nfs_read_data
*
rdata
;
rdata
=
nfs_readdata_alloc
();
rdata
=
nfs_readdata_alloc
(
1
);
if
(
!
rdata
)
return
-
ENOMEM
;
...
...
@@ -220,9 +219,6 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
NFS_PROTO
(
inode
)
->
read_setup
(
data
);
data
->
task
.
tk_cookie
=
(
unsigned
long
)
inode
;
data
->
task
.
tk_calldata
=
data
;
/* Release requests */
data
->
task
.
tk_release
=
nfs_readdata_release
;
dprintk
(
"NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)
\n
"
,
data
->
task
.
tk_pid
,
...
...
@@ -287,7 +283,7 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode)
nbytes
=
req
->
wb_bytes
;
for
(;;)
{
data
=
nfs_readdata_alloc
();
data
=
nfs_readdata_alloc
(
1
);
if
(
!
data
)
goto
out_bad
;
INIT_LIST_HEAD
(
&
data
->
pages
);
...
...
@@ -343,7 +339,7 @@ static int nfs_pagein_one(struct list_head *head, struct inode *inode)
if
(
NFS_SERVER
(
inode
)
->
rsize
<
PAGE_CACHE_SIZE
)
return
nfs_pagein_multi
(
head
,
inode
);
data
=
nfs_readdata_alloc
();
data
=
nfs_readdata_alloc
(
NFS_SERVER
(
inode
)
->
rpages
);
if
(
!
data
)
goto
out_bad
;
...
...
@@ -452,9 +448,9 @@ static void nfs_readpage_result_full(struct nfs_read_data *data, int status)
* This is the callback from RPC telling us whether a reply was
* received or some error occurred (timeout or socket shutdown).
*/
void
nfs_readpage_result
(
struct
rpc_task
*
task
)
void
nfs_readpage_result
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_read_data
*
data
=
(
struct
nfs_read_data
*
)
task
->
tk_
calldata
;
struct
nfs_read_data
*
data
=
calldata
;
struct
nfs_readargs
*
argp
=
&
data
->
args
;
struct
nfs_readres
*
resp
=
&
data
->
res
;
int
status
=
task
->
tk_status
;
...
...
fs/nfs/sysctl.c
0 → 100644
浏览文件 @
47853e7f
/*
* linux/fs/nfs/sysctl.c
*
* Sysctl interface to NFS parameters
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/sysctl.h>
#include <linux/module.h>
#include <linux/nfs4.h>
#include <linux/nfs_idmap.h>
#include "callback.h"
static
const
int
nfs_set_port_min
=
0
;
static
const
int
nfs_set_port_max
=
65535
;
static
struct
ctl_table_header
*
nfs_callback_sysctl_table
;
/*
* Something that isn't CTL_ANY, CTL_NONE or a value that may clash.
* Use the same values as fs/lockd/svc.c
*/
#define CTL_UNNUMBERED -2
static
ctl_table
nfs_cb_sysctls
[]
=
{
#ifdef CONFIG_NFS_V4
{
.
ctl_name
=
CTL_UNNUMBERED
,
.
procname
=
"nfs_callback_tcpport"
,
.
data
=
&
nfs_callback_set_tcpport
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_minmax
,
.
extra1
=
(
int
*
)
&
nfs_set_port_min
,
.
extra2
=
(
int
*
)
&
nfs_set_port_max
,
},
{
.
ctl_name
=
CTL_UNNUMBERED
,
.
procname
=
"idmap_cache_timeout"
,
.
data
=
&
nfs_idmap_cache_timeout
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec_jiffies
,
.
strategy
=
&
sysctl_jiffies
,
},
#endif
{
.
ctl_name
=
0
}
};
static
ctl_table
nfs_cb_sysctl_dir
[]
=
{
{
.
ctl_name
=
CTL_UNNUMBERED
,
.
procname
=
"nfs"
,
.
mode
=
0555
,
.
child
=
nfs_cb_sysctls
,
},
{
.
ctl_name
=
0
}
};
static
ctl_table
nfs_cb_sysctl_root
[]
=
{
{
.
ctl_name
=
CTL_FS
,
.
procname
=
"fs"
,
.
mode
=
0555
,
.
child
=
nfs_cb_sysctl_dir
,
},
{
.
ctl_name
=
0
}
};
int
nfs_register_sysctl
(
void
)
{
nfs_callback_sysctl_table
=
register_sysctl_table
(
nfs_cb_sysctl_root
,
0
);
if
(
nfs_callback_sysctl_table
==
NULL
)
return
-
ENOMEM
;
return
0
;
}
void
nfs_unregister_sysctl
(
void
)
{
unregister_sysctl_table
(
nfs_callback_sysctl_table
);
nfs_callback_sysctl_table
=
NULL
;
}
fs/nfs/unlink.c
浏览文件 @
47853e7f
...
...
@@ -87,10 +87,9 @@ nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data)
* We delay initializing RPC info until after the call to dentry_iput()
* in order to minimize races against rename().
*/
static
void
nfs_async_unlink_init
(
struct
rpc_task
*
task
)
static
void
nfs_async_unlink_init
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_unlinkdata
*
data
=
(
struct
nfs_unlinkdata
*
)
task
->
tk_
calldata
;
struct
nfs_unlinkdata
*
data
=
calldata
;
struct
dentry
*
dir
=
data
->
dir
;
struct
rpc_message
msg
=
{
.
rpc_cred
=
data
->
cred
,
...
...
@@ -116,10 +115,9 @@ nfs_async_unlink_init(struct rpc_task *task)
*
* Do the directory attribute update.
*/
static
void
nfs_async_unlink_done
(
struct
rpc_task
*
task
)
static
void
nfs_async_unlink_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_unlinkdata
*
data
=
(
struct
nfs_unlinkdata
*
)
task
->
tk_
calldata
;
struct
nfs_unlinkdata
*
data
=
calldata
;
struct
dentry
*
dir
=
data
->
dir
;
struct
inode
*
dir_i
;
...
...
@@ -141,13 +139,18 @@ nfs_async_unlink_done(struct rpc_task *task)
* We need to call nfs_put_unlinkdata as a 'tk_release' task since the
* rpc_task would be freed too.
*/
static
void
nfs_async_unlink_release
(
struct
rpc_task
*
task
)
static
void
nfs_async_unlink_release
(
void
*
calldata
)
{
struct
nfs_unlinkdata
*
data
=
(
struct
nfs_unlinkdata
*
)
task
->
tk_
calldata
;
struct
nfs_unlinkdata
*
data
=
calldata
;
nfs_put_unlinkdata
(
data
);
}
static
const
struct
rpc_call_ops
nfs_unlink_ops
=
{
.
rpc_call_prepare
=
nfs_async_unlink_init
,
.
rpc_call_done
=
nfs_async_unlink_done
,
.
rpc_release
=
nfs_async_unlink_release
,
};
/**
* nfs_async_unlink - asynchronous unlinking of a file
* @dentry: dentry to unlink
...
...
@@ -157,7 +160,6 @@ nfs_async_unlink(struct dentry *dentry)
{
struct
dentry
*
dir
=
dentry
->
d_parent
;
struct
nfs_unlinkdata
*
data
;
struct
rpc_task
*
task
;
struct
rpc_clnt
*
clnt
=
NFS_CLIENT
(
dir
->
d_inode
);
int
status
=
-
ENOMEM
;
...
...
@@ -178,17 +180,13 @@ nfs_async_unlink(struct dentry *dentry)
nfs_deletes
=
data
;
data
->
count
=
1
;
task
=
&
data
->
task
;
rpc_init_task
(
task
,
clnt
,
nfs_async_unlink_done
,
RPC_TASK_ASYNC
);
task
->
tk_calldata
=
data
;
task
->
tk_action
=
nfs_async_unlink_init
;
task
->
tk_release
=
nfs_async_unlink_release
;
rpc_init_task
(
&
data
->
task
,
clnt
,
RPC_TASK_ASYNC
,
&
nfs_unlink_ops
,
data
);
spin_lock
(
&
dentry
->
d_lock
);
dentry
->
d_flags
|=
DCACHE_NFSFS_RENAMED
;
spin_unlock
(
&
dentry
->
d_lock
);
rpc_sleep_on
(
&
nfs_delete_queue
,
task
,
NULL
,
NULL
);
rpc_sleep_on
(
&
nfs_delete_queue
,
&
data
->
task
,
NULL
,
NULL
);
status
=
0
;
out:
return
status
;
...
...
fs/nfs/write.c
浏览文件 @
47853e7f
...
...
@@ -89,24 +89,38 @@ static mempool_t *nfs_commit_mempool;
static
DECLARE_WAIT_QUEUE_HEAD
(
nfs_write_congestion
);
static
inline
struct
nfs_write_data
*
nfs_commit_alloc
(
void
)
static
inline
struct
nfs_write_data
*
nfs_commit_alloc
(
unsigned
int
pagecount
)
{
struct
nfs_write_data
*
p
=
mempool_alloc
(
nfs_commit_mempool
,
SLAB_NOFS
);
if
(
p
)
{
memset
(
p
,
0
,
sizeof
(
*
p
));
INIT_LIST_HEAD
(
&
p
->
pages
);
if
(
pagecount
<
NFS_PAGEVEC_SIZE
)
p
->
pagevec
=
&
p
->
page_array
[
0
];
else
{
size_t
size
=
++
pagecount
*
sizeof
(
struct
page
*
);
p
->
pagevec
=
kmalloc
(
size
,
GFP_NOFS
);
if
(
p
->
pagevec
)
{
memset
(
p
->
pagevec
,
0
,
size
);
}
else
{
mempool_free
(
p
,
nfs_commit_mempool
);
p
=
NULL
;
}
}
}
return
p
;
}
static
inline
void
nfs_commit_free
(
struct
nfs_write_data
*
p
)
{
if
(
p
&&
(
p
->
pagevec
!=
&
p
->
page_array
[
0
]))
kfree
(
p
->
pagevec
);
mempool_free
(
p
,
nfs_commit_mempool
);
}
static
void
nfs_writedata_release
(
struct
rpc_task
*
task
)
void
nfs_writedata_release
(
void
*
wdata
)
{
struct
nfs_write_data
*
wdata
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
nfs_writedata_free
(
wdata
);
}
...
...
@@ -168,7 +182,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
int
result
,
written
=
0
;
struct
nfs_write_data
*
wdata
;
wdata
=
nfs_writedata_alloc
();
wdata
=
nfs_writedata_alloc
(
1
);
if
(
!
wdata
)
return
-
ENOMEM
;
...
...
@@ -232,19 +246,16 @@ static int nfs_writepage_async(struct nfs_open_context *ctx,
unsigned
int
offset
,
unsigned
int
count
)
{
struct
nfs_page
*
req
;
int
status
;
req
=
nfs_update_request
(
ctx
,
inode
,
page
,
offset
,
count
);
status
=
(
IS_ERR
(
req
))
?
PTR_ERR
(
req
)
:
0
;
if
(
status
<
0
)
goto
out
;
if
(
IS_ERR
(
req
))
return
PTR_ERR
(
req
);
/* Update file length */
nfs_grow_file
(
page
,
offset
,
count
);
/* Set the PG_uptodate flag? */
nfs_mark_uptodate
(
page
,
offset
,
count
);
nfs_unlock_request
(
req
);
out:
return
status
;
return
0
;
}
static
int
wb_priority
(
struct
writeback_control
*
wbc
)
...
...
@@ -304,11 +315,8 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
lock_kernel
();
if
(
!
IS_SYNC
(
inode
)
&&
inode_referenced
)
{
err
=
nfs_writepage_async
(
ctx
,
inode
,
page
,
0
,
offset
);
if
(
err
>=
0
)
{
err
=
0
;
if
(
wbc
->
for_reclaim
)
nfs_flush_inode
(
inode
,
0
,
0
,
FLUSH_STABLE
);
}
if
(
!
wbc
->
for_writepages
)
nfs_flush_inode
(
inode
,
0
,
0
,
wb_priority
(
wbc
));
}
else
{
err
=
nfs_writepage_sync
(
ctx
,
inode
,
page
,
0
,
offset
,
priority
);
...
...
@@ -877,9 +885,6 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
data
->
task
.
tk_priority
=
flush_task_priority
(
how
);
data
->
task
.
tk_cookie
=
(
unsigned
long
)
inode
;
data
->
task
.
tk_calldata
=
data
;
/* Release requests */
data
->
task
.
tk_release
=
nfs_writedata_release
;
dprintk
(
"NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)
\n
"
,
data
->
task
.
tk_pid
,
...
...
@@ -919,7 +924,7 @@ static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how)
nbytes
=
req
->
wb_bytes
;
for
(;;)
{
data
=
nfs_writedata_alloc
();
data
=
nfs_writedata_alloc
(
1
);
if
(
!
data
)
goto
out_bad
;
list_add
(
&
data
->
pages
,
&
list
);
...
...
@@ -983,7 +988,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how)
if
(
NFS_SERVER
(
inode
)
->
wsize
<
PAGE_CACHE_SIZE
)
return
nfs_flush_multi
(
head
,
inode
,
how
);
data
=
nfs_writedata_alloc
();
data
=
nfs_writedata_alloc
(
NFS_SERVER
(
inode
)
->
wpages
);
if
(
!
data
)
goto
out_bad
;
...
...
@@ -1137,9 +1142,9 @@ static void nfs_writeback_done_full(struct nfs_write_data *data, int status)
/*
* This function is called when the WRITE call is complete.
*/
void
nfs_writeback_done
(
struct
rpc_task
*
task
)
void
nfs_writeback_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_
calldata
;
struct
nfs_write_data
*
data
=
calldata
;
struct
nfs_writeargs
*
argp
=
&
data
->
args
;
struct
nfs_writeres
*
resp
=
&
data
->
res
;
...
...
@@ -1206,9 +1211,8 @@ void nfs_writeback_done(struct rpc_task *task)
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
static
void
nfs_commit_release
(
struct
rpc_task
*
task
)
void
nfs_commit_release
(
void
*
wdata
)
{
struct
nfs_write_data
*
wdata
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
nfs_commit_free
(
wdata
);
}
...
...
@@ -1244,9 +1248,6 @@ static void nfs_commit_rpcsetup(struct list_head *head,
data
->
task
.
tk_priority
=
flush_task_priority
(
how
);
data
->
task
.
tk_cookie
=
(
unsigned
long
)
inode
;
data
->
task
.
tk_calldata
=
data
;
/* Release requests */
data
->
task
.
tk_release
=
nfs_commit_release
;
dprintk
(
"NFS: %4d initiated commit call
\n
"
,
data
->
task
.
tk_pid
);
}
...
...
@@ -1255,12 +1256,12 @@ static void nfs_commit_rpcsetup(struct list_head *head,
* Commit dirty pages
*/
static
int
nfs_commit_list
(
struct
list_head
*
head
,
int
how
)
nfs_commit_list
(
struct
inode
*
inode
,
struct
list_head
*
head
,
int
how
)
{
struct
nfs_write_data
*
data
;
struct
nfs_page
*
req
;
data
=
nfs_commit_alloc
();
data
=
nfs_commit_alloc
(
NFS_SERVER
(
inode
)
->
wpages
);
if
(
!
data
)
goto
out_bad
;
...
...
@@ -1283,10 +1284,9 @@ nfs_commit_list(struct list_head *head, int how)
/*
* COMMIT call returned
*/
void
nfs_commit_done
(
struct
rpc_task
*
task
)
void
nfs_commit_done
(
struct
rpc_task
*
task
,
void
*
calldata
)
{
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_
calldata
;
struct
nfs_write_data
*
data
=
calldata
;
struct
nfs_page
*
req
;
int
res
=
0
;
...
...
@@ -1366,7 +1366,7 @@ int nfs_commit_inode(struct inode *inode, int how)
res
=
nfs_scan_commit
(
inode
,
&
head
,
0
,
0
);
spin_unlock
(
&
nfsi
->
req_lock
);
if
(
res
)
{
error
=
nfs_commit_list
(
&
head
,
how
);
error
=
nfs_commit_list
(
inode
,
&
head
,
how
);
if
(
error
<
0
)
return
error
;
}
...
...
@@ -1377,22 +1377,23 @@ int nfs_commit_inode(struct inode *inode, int how)
int
nfs_sync_inode
(
struct
inode
*
inode
,
unsigned
long
idx_start
,
unsigned
int
npages
,
int
how
)
{
int
error
,
wait
;
int
nocommit
=
how
&
FLUSH_NOCOMMIT
;
int
wait
=
how
&
FLUSH_WAIT
;
int
error
;
wait
=
how
&
FLUSH_WAIT
;
how
&=
~
FLUSH_WAIT
;
how
&=
~
(
FLUSH_WAIT
|
FLUSH_NOCOMMIT
);
do
{
error
=
0
;
if
(
wait
)
if
(
wait
)
{
error
=
nfs_wait_on_requests
(
inode
,
idx_start
,
npages
);
if
(
error
==
0
)
if
(
error
!=
0
)
continue
;
}
error
=
nfs_flush_inode
(
inode
,
idx_start
,
npages
,
how
);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if
(
error
==
0
)
if
(
error
!=
0
)
continue
;
if
(
!
nocommit
)
error
=
nfs_commit_inode
(
inode
,
how
);
#endif
}
while
(
error
>
0
);
return
error
;
}
...
...
fs/nfsd/nfs4callback.c
浏览文件 @
47853e7f
...
...
@@ -53,7 +53,7 @@
#define NFSPROC4_CB_COMPOUND 1
/* declarations */
static
void
nfs4_cb_null
(
struct
rpc_task
*
task
)
;
static
const
struct
rpc_call_ops
nfs4_cb_null_ops
;
/* Index of predefined Linux callback client operations */
...
...
@@ -431,7 +431,6 @@ nfsd4_probe_callback(struct nfs4_client *clp)
}
clnt
->
cl_intr
=
0
;
clnt
->
cl_softrtry
=
1
;
clnt
->
cl_chatty
=
1
;
/* Kick rpciod, put the call on the wire. */
...
...
@@ -447,7 +446,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
msg
.
rpc_cred
=
nfsd4_lookupcred
(
clp
,
0
);
if
(
IS_ERR
(
msg
.
rpc_cred
))
goto
out_rpciod
;
status
=
rpc_call_async
(
clnt
,
&
msg
,
RPC_TASK_ASYNC
,
nfs4_cb_null
,
NULL
);
status
=
rpc_call_async
(
clnt
,
&
msg
,
RPC_TASK_ASYNC
,
&
nfs4_cb_null_ops
,
NULL
);
put_rpccred
(
msg
.
rpc_cred
);
if
(
status
!=
0
)
{
...
...
@@ -469,7 +468,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
}
static
void
nfs4_cb_null
(
struct
rpc_task
*
task
)
nfs4_cb_null
(
struct
rpc_task
*
task
,
void
*
dummy
)
{
struct
nfs4_client
*
clp
=
(
struct
nfs4_client
*
)
task
->
tk_msg
.
rpc_argp
;
struct
nfs4_callback
*
cb
=
&
clp
->
cl_callback
;
...
...
@@ -488,6 +487,10 @@ nfs4_cb_null(struct rpc_task *task)
put_nfs4_client
(
clp
);
}
static
const
struct
rpc_call_ops
nfs4_cb_null_ops
=
{
.
rpc_call_done
=
nfs4_cb_null
,
};
/*
* called with dp->dl_count inc'ed.
* nfs4_lock_state() may or may not have been called.
...
...
include/linux/fs.h
浏览文件 @
47853e7f
...
...
@@ -760,7 +760,7 @@ extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
extern
int
posix_lock_file
(
struct
file
*
,
struct
file_lock
*
);
extern
int
posix_lock_file_wait
(
struct
file
*
,
struct
file_lock
*
);
extern
void
posix_block_lock
(
struct
file_lock
*
,
struct
file_lock
*
);
extern
void
posix_unblock_lock
(
struct
file
*
,
struct
file_lock
*
);
extern
int
posix_unblock_lock
(
struct
file
*
,
struct
file_lock
*
);
extern
int
posix_locks_deadlock
(
struct
file_lock
*
,
struct
file_lock
*
);
extern
int
flock_lock_file_wait
(
struct
file
*
filp
,
struct
file_lock
*
fl
);
extern
int
__break_lease
(
struct
inode
*
inode
,
unsigned
int
flags
);
...
...
include/linux/lockd/lockd.h
浏览文件 @
47853e7f
...
...
@@ -172,7 +172,7 @@ extern struct nlm_host *nlm_find_client(void);
/*
* Server-side lock handling
*/
int
nlmsvc_async_call
(
struct
nlm_rqst
*
,
u32
,
rpc_action
);
int
nlmsvc_async_call
(
struct
nlm_rqst
*
,
u32
,
const
struct
rpc_call_ops
*
);
u32
nlmsvc_lock
(
struct
svc_rqst
*
,
struct
nlm_file
*
,
struct
nlm_lock
*
,
int
,
struct
nlm_cookie
*
);
u32
nlmsvc_unlock
(
struct
nlm_file
*
,
struct
nlm_lock
*
);
...
...
include/linux/nfs_fs.h
浏览文件 @
47853e7f
...
...
@@ -38,9 +38,6 @@
# define NFS_DEBUG
#endif
#define NFS_MAX_FILE_IO_BUFFER_SIZE 32768
#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096
/* Default timeout values */
#define NFS_MAX_UDP_TIMEOUT (60*HZ)
#define NFS_MAX_TCP_TIMEOUT (600*HZ)
...
...
@@ -65,6 +62,7 @@
#define FLUSH_STABLE 4
/* commit to stable storage */
#define FLUSH_LOWPRI 8
/* low priority background flush */
#define FLUSH_HIGHPRI 16
/* high priority memory reclaim flush */
#define FLUSH_NOCOMMIT 32
/* Don't send the NFSv3/v4 COMMIT */
#ifdef __KERNEL__
...
...
@@ -393,6 +391,17 @@ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_
*/
extern
struct
inode_operations
nfs_symlink_inode_operations
;
/*
* linux/fs/nfs/sysctl.c
*/
#ifdef CONFIG_SYSCTL
extern
int
nfs_register_sysctl
(
void
);
extern
void
nfs_unregister_sysctl
(
void
);
#else
#define nfs_register_sysctl() do { } while(0)
#define nfs_unregister_sysctl() do { } while(0)
#endif
/*
* linux/fs/nfs/unlink.c
*/
...
...
@@ -406,10 +415,12 @@ extern int nfs_writepage(struct page *page, struct writeback_control *wbc);
extern
int
nfs_writepages
(
struct
address_space
*
,
struct
writeback_control
*
);
extern
int
nfs_flush_incompatible
(
struct
file
*
file
,
struct
page
*
page
);
extern
int
nfs_updatepage
(
struct
file
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
);
extern
void
nfs_writeback_done
(
struct
rpc_task
*
task
);
extern
void
nfs_writeback_done
(
struct
rpc_task
*
task
,
void
*
data
);
extern
void
nfs_writedata_release
(
void
*
data
);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
extern
void
nfs_commit_done
(
struct
rpc_task
*
);
extern
void
nfs_commit_done
(
struct
rpc_task
*
,
void
*
data
);
extern
void
nfs_commit_release
(
void
*
data
);
#endif
/*
...
...
@@ -460,18 +471,33 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page)
*/
extern
mempool_t
*
nfs_wdata_mempool
;
static
inline
struct
nfs_write_data
*
nfs_writedata_alloc
(
void
)
static
inline
struct
nfs_write_data
*
nfs_writedata_alloc
(
unsigned
int
pagecount
)
{
struct
nfs_write_data
*
p
=
mempool_alloc
(
nfs_wdata_mempool
,
SLAB_NOFS
);
if
(
p
)
{
memset
(
p
,
0
,
sizeof
(
*
p
));
INIT_LIST_HEAD
(
&
p
->
pages
);
if
(
pagecount
<
NFS_PAGEVEC_SIZE
)
p
->
pagevec
=
&
p
->
page_array
[
0
];
else
{
size_t
size
=
++
pagecount
*
sizeof
(
struct
page
*
);
p
->
pagevec
=
kmalloc
(
size
,
GFP_NOFS
);
if
(
p
->
pagevec
)
{
memset
(
p
->
pagevec
,
0
,
size
);
}
else
{
mempool_free
(
p
,
nfs_wdata_mempool
);
p
=
NULL
;
}
}
}
return
p
;
}
static
inline
void
nfs_writedata_free
(
struct
nfs_write_data
*
p
)
{
if
(
p
&&
(
p
->
pagevec
!=
&
p
->
page_array
[
0
]))
kfree
(
p
->
pagevec
);
mempool_free
(
p
,
nfs_wdata_mempool
);
}
...
...
@@ -481,28 +507,45 @@ static inline void nfs_writedata_free(struct nfs_write_data *p)
extern
int
nfs_readpage
(
struct
file
*
,
struct
page
*
);
extern
int
nfs_readpages
(
struct
file
*
,
struct
address_space
*
,
struct
list_head
*
,
unsigned
);
extern
void
nfs_readpage_result
(
struct
rpc_task
*
);
extern
void
nfs_readpage_result
(
struct
rpc_task
*
,
void
*
);
extern
void
nfs_readdata_release
(
void
*
data
);
/*
* Allocate and free nfs_read_data structures
*/
extern
mempool_t
*
nfs_rdata_mempool
;
static
inline
struct
nfs_read_data
*
nfs_readdata_alloc
(
void
)
static
inline
struct
nfs_read_data
*
nfs_readdata_alloc
(
unsigned
int
pagecount
)
{
struct
nfs_read_data
*
p
=
mempool_alloc
(
nfs_rdata_mempool
,
SLAB_NOFS
);
if
(
p
)
if
(
p
)
{
memset
(
p
,
0
,
sizeof
(
*
p
));
INIT_LIST_HEAD
(
&
p
->
pages
);
if
(
pagecount
<
NFS_PAGEVEC_SIZE
)
p
->
pagevec
=
&
p
->
page_array
[
0
];
else
{
size_t
size
=
++
pagecount
*
sizeof
(
struct
page
*
);
p
->
pagevec
=
kmalloc
(
size
,
GFP_NOFS
);
if
(
p
->
pagevec
)
{
memset
(
p
->
pagevec
,
0
,
size
);
}
else
{
mempool_free
(
p
,
nfs_rdata_mempool
);
p
=
NULL
;
}
}
}
return
p
;
}
static
inline
void
nfs_readdata_free
(
struct
nfs_read_data
*
p
)
{
if
(
p
&&
(
p
->
pagevec
!=
&
p
->
page_array
[
0
]))
kfree
(
p
->
pagevec
);
mempool_free
(
p
,
nfs_rdata_mempool
);
}
extern
void
nfs_readdata_release
(
struct
rpc_task
*
task
);
/*
* linux/fs/nfs3proc.c
*/
...
...
include/linux/nfs_idmap.h
浏览文件 @
47853e7f
...
...
@@ -71,6 +71,8 @@ int nfs_map_name_to_uid(struct nfs4_client *, const char *, size_t, __u32 *);
int
nfs_map_group_to_gid
(
struct
nfs4_client
*
,
const
char
*
,
size_t
,
__u32
*
);
int
nfs_map_uid_to_name
(
struct
nfs4_client
*
,
__u32
,
char
*
);
int
nfs_map_gid_to_group
(
struct
nfs4_client
*
,
__u32
,
char
*
);
extern
unsigned
int
nfs_idmap_cache_timeout
;
#endif
/* __KERNEL__ */
#endif
/* NFS_IDMAP_H */
include/linux/nfs_page.h
浏览文件 @
47853e7f
...
...
@@ -79,9 +79,7 @@ extern void nfs_clear_page_writeback(struct nfs_page *req);
static
inline
int
nfs_lock_request_dontget
(
struct
nfs_page
*
req
)
{
if
(
test_and_set_bit
(
PG_BUSY
,
&
req
->
wb_flags
))
return
0
;
return
1
;
return
!
test_and_set_bit
(
PG_BUSY
,
&
req
->
wb_flags
);
}
/*
...
...
@@ -125,9 +123,7 @@ nfs_list_remove_request(struct nfs_page *req)
static
inline
int
nfs_defer_commit
(
struct
nfs_page
*
req
)
{
if
(
test_and_set_bit
(
PG_NEED_COMMIT
,
&
req
->
wb_flags
))
return
0
;
return
1
;
return
!
test_and_set_bit
(
PG_NEED_COMMIT
,
&
req
->
wb_flags
);
}
static
inline
void
...
...
@@ -141,9 +137,7 @@ nfs_clear_commit(struct nfs_page *req)
static
inline
int
nfs_defer_reschedule
(
struct
nfs_page
*
req
)
{
if
(
test_and_set_bit
(
PG_NEED_RESCHED
,
&
req
->
wb_flags
))
return
0
;
return
1
;
return
!
test_and_set_bit
(
PG_NEED_RESCHED
,
&
req
->
wb_flags
);
}
static
inline
void
...
...
include/linux/nfs_xdr.h
浏览文件 @
47853e7f
...
...
@@ -4,6 +4,16 @@
#include <linux/sunrpc/xprt.h>
#include <linux/nfsacl.h>
/*
* To change the maximum rsize and wsize supported by the NFS client, adjust
* NFS_MAX_FILE_IO_SIZE. 64KB is a typical maximum, but some servers can
* support a megabyte or more. The default is left at 4096 bytes, which is
* reasonable for NFS over UDP.
*/
#define NFS_MAX_FILE_IO_SIZE (1048576U)
#define NFS_DEF_FILE_IO_SIZE (4096U)
#define NFS_MIN_FILE_IO_SIZE (1024U)
struct
nfs4_fsid
{
__u64
major
;
__u64
minor
;
...
...
@@ -137,7 +147,7 @@ struct nfs_openres {
*/
struct
nfs_open_confirmargs
{
const
struct
nfs_fh
*
fh
;
nfs4_stateid
stateid
;
nfs4_stateid
*
stateid
;
struct
nfs_seqid
*
seqid
;
};
...
...
@@ -169,62 +179,58 @@ struct nfs_lowner {
u32
id
;
};
struct
nfs_lock_opargs
{
struct
nfs_lock_args
{
struct
nfs_fh
*
fh
;
struct
file_lock
*
fl
;
struct
nfs_seqid
*
lock_seqid
;
nfs4_stateid
*
lock_stateid
;
struct
nfs_seqid
*
open_seqid
;
nfs4_stateid
*
open_stateid
;
struct
nfs_lowner
lock_owner
;
__u32
reclaim
;
__u32
new_lock_owner
;
unsigned
char
block
:
1
;
unsigned
char
reclaim
:
1
;
unsigned
char
new_lock_owner
:
1
;
};
struct
nfs_lock_res
{
nfs4_stateid
stateid
;
};
struct
nfs_locku_opargs
{
struct
nfs_locku_args
{
struct
nfs_fh
*
fh
;
struct
file_lock
*
fl
;
struct
nfs_seqid
*
seqid
;
nfs4_stateid
*
stateid
;
};
struct
nfs_lockargs
{
struct
nfs_fh
*
fh
;
__u32
type
;
__u64
offset
;
__u64
length
;
union
{
struct
nfs_lock_opargs
*
lock
;
/* LOCK */
struct
nfs_lowner
*
lockt
;
/* LOCKT */
struct
nfs_locku_opargs
*
locku
;
/* LOCKU */
}
u
;
struct
nfs_locku_res
{
nfs4_stateid
stateid
;
};
struct
nfs_lock_denied
{
__u64
offset
;
__u64
length
;
__u32
type
;
struct
nfs_lowner
owner
;
struct
nfs_lockt_args
{
struct
nfs_fh
*
fh
;
struct
file_lock
*
fl
;
struct
nfs_lowner
lock_owner
;
};
struct
nfs_lockres
{
union
{
nfs4_stateid
stateid
;
/* LOCK success, LOCKU */
struct
nfs_lock_denied
denied
;
/* LOCK failed, LOCKT success */
}
u
;
const
struct
nfs_server
*
server
;
struct
nfs_lockt_res
{
struct
file_lock
*
denied
;
/* LOCK, LOCKT failed */
};
struct
nfs4_delegreturnargs
{
const
struct
nfs_fh
*
fhandle
;
const
nfs4_stateid
*
stateid
;
const
u32
*
bitmask
;
};
struct
nfs4_delegreturnres
{
struct
nfs_fattr
*
fattr
;
const
struct
nfs_server
*
server
;
};
/*
* Arguments to the read call.
*/
#define NFS_READ_MAXIOV (9U)
#if (NFS_READ_MAXIOV > (MAX_IOVEC -2))
#error "NFS_READ_MAXIOV is too large"
#endif
struct
nfs_readargs
{
struct
nfs_fh
*
fh
;
struct
nfs_open_context
*
context
;
...
...
@@ -243,11 +249,6 @@ struct nfs_readres {
/*
* Arguments to the write call.
*/
#define NFS_WRITE_MAXIOV (9U)
#if (NFS_WRITE_MAXIOV > (MAX_IOVEC -2))
#error "NFS_WRITE_MAXIOV is too large"
#endif
struct
nfs_writeargs
{
struct
nfs_fh
*
fh
;
struct
nfs_open_context
*
context
;
...
...
@@ -678,6 +679,8 @@ struct nfs4_server_caps_res {
struct
nfs_page
;
#define NFS_PAGEVEC_SIZE (8U)
struct
nfs_read_data
{
int
flags
;
struct
rpc_task
task
;
...
...
@@ -686,13 +689,14 @@ struct nfs_read_data {
struct
nfs_fattr
fattr
;
/* fattr storage */
struct
list_head
pages
;
/* Coalesced read requests */
struct
nfs_page
*
req
;
/* multi ops per nfs_page */
struct
page
*
pagevec
[
NFS_READ_MAXIOV
]
;
struct
page
*
*
pagevec
;
struct
nfs_readargs
args
;
struct
nfs_readres
res
;
#ifdef CONFIG_NFS_V4
unsigned
long
timestamp
;
/* For lease renewal */
#endif
void
(
*
complete
)
(
struct
nfs_read_data
*
,
int
);
struct
page
*
page_array
[
NFS_PAGEVEC_SIZE
+
1
];
};
struct
nfs_write_data
{
...
...
@@ -704,13 +708,14 @@ struct nfs_write_data {
struct
nfs_writeverf
verf
;
struct
list_head
pages
;
/* Coalesced requests we wish to flush */
struct
nfs_page
*
req
;
/* multi ops per nfs_page */
struct
page
*
pagevec
[
NFS_WRITE_MAXIOV
]
;
struct
page
*
*
pagevec
;
struct
nfs_writeargs
args
;
/* argument struct */
struct
nfs_writeres
res
;
/* result struct */
#ifdef CONFIG_NFS_V4
unsigned
long
timestamp
;
/* For lease renewal */
#endif
void
(
*
complete
)
(
struct
nfs_write_data
*
,
int
);
struct
page
*
page_array
[
NFS_PAGEVEC_SIZE
+
1
];
};
struct
nfs_access_entry
;
...
...
include/linux/sunrpc/clnt.h
浏览文件 @
47853e7f
...
...
@@ -49,7 +49,6 @@ struct rpc_clnt {
unsigned
int
cl_softrtry
:
1
,
/* soft timeouts */
cl_intr
:
1
,
/* interruptible */
cl_chatty
:
1
,
/* be verbose */
cl_autobind
:
1
,
/* use getport() */
cl_oneshot
:
1
,
/* dispose after use */
cl_dead
:
1
;
/* abandoned */
...
...
@@ -126,7 +125,8 @@ int rpc_register(u32, u32, int, unsigned short, int *);
void
rpc_call_setup
(
struct
rpc_task
*
,
struct
rpc_message
*
,
int
);
int
rpc_call_async
(
struct
rpc_clnt
*
clnt
,
struct
rpc_message
*
msg
,
int
flags
,
rpc_action
callback
,
void
*
clntdata
);
int
flags
,
const
struct
rpc_call_ops
*
tk_ops
,
void
*
calldata
);
int
rpc_call_sync
(
struct
rpc_clnt
*
clnt
,
struct
rpc_message
*
msg
,
int
flags
);
void
rpc_restart_call
(
struct
rpc_task
*
);
...
...
@@ -134,6 +134,7 @@ void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
void
rpc_clnt_sigunmask
(
struct
rpc_clnt
*
clnt
,
sigset_t
*
oldset
);
void
rpc_setbufsize
(
struct
rpc_clnt
*
,
unsigned
int
,
unsigned
int
);
size_t
rpc_max_payload
(
struct
rpc_clnt
*
);
void
rpc_force_rebind
(
struct
rpc_clnt
*
);
int
rpc_ping
(
struct
rpc_clnt
*
clnt
,
int
flags
);
static
__inline__
...
...
include/linux/sunrpc/gss_spkm3.h
浏览文件 @
47853e7f
...
...
@@ -48,7 +48,7 @@ u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struc
#define CKSUMTYPE_RSA_MD5 0x0007
s32
make_checksum
(
s32
cksumtype
,
char
*
header
,
int
hdrlen
,
struct
xdr_buf
*
body
,
struct
xdr_netobj
*
cksum
);
int
body_offset
,
struct
xdr_netobj
*
cksum
);
void
asn1_bitstring_len
(
struct
xdr_netobj
*
in
,
int
*
enclen
,
int
*
zerobits
);
int
decode_asn1_bitstring
(
struct
xdr_netobj
*
out
,
char
*
in
,
int
enclen
,
int
explen
);
...
...
include/linux/sunrpc/sched.h
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
include/linux/sunrpc/xdr.h
浏览文件 @
47853e7f
...
...
@@ -91,7 +91,6 @@ struct xdr_buf {
u32
*
xdr_encode_opaque_fixed
(
u32
*
p
,
const
void
*
ptr
,
unsigned
int
len
);
u32
*
xdr_encode_opaque
(
u32
*
p
,
const
void
*
ptr
,
unsigned
int
len
);
u32
*
xdr_encode_string
(
u32
*
p
,
const
char
*
s
);
u32
*
xdr_decode_string
(
u32
*
p
,
char
**
sp
,
int
*
lenp
,
int
maxlen
);
u32
*
xdr_decode_string_inplace
(
u32
*
p
,
char
**
sp
,
int
*
lenp
,
int
maxlen
);
u32
*
xdr_encode_netobj
(
u32
*
p
,
const
struct
xdr_netobj
*
);
u32
*
xdr_decode_netobj
(
u32
*
p
,
struct
xdr_netobj
*
);
...
...
@@ -134,11 +133,6 @@ xdr_adjust_iovec(struct kvec *iov, u32 *p)
return
iov
->
iov_len
=
((
u8
*
)
p
-
(
u8
*
)
iov
->
iov_base
);
}
/*
* Maximum number of iov's we use.
*/
#define MAX_IOVEC (12)
/*
* XDR buffer helper functions
*/
...
...
include/linux/sunrpc/xprt.h
浏览文件 @
47853e7f
...
...
@@ -79,21 +79,19 @@ struct rpc_rqst {
void
(
*
rq_release_snd_buf
)(
struct
rpc_rqst
*
);
/* release rq_enc_pages */
struct
list_head
rq_list
;
__u32
*
rq_buffer
;
/* XDR encode buffer */
size_t
rq_bufsize
;
struct
xdr_buf
rq_private_buf
;
/* The receive buffer
* used in the softirq.
*/
unsigned
long
rq_majortimeo
;
/* major timeout alarm */
unsigned
long
rq_timeout
;
/* Current timeout value */
unsigned
int
rq_retries
;
/* # of retries */
/*
* For authentication (e.g. auth_des)
*/
u32
rq_creddata
[
2
];
/*
* Partial send handling
*/
u32
rq_bytes_sent
;
/* Bytes we have sent */
unsigned
long
rq_xtime
;
/* when transmitted */
...
...
@@ -106,7 +104,10 @@ struct rpc_xprt_ops {
void
(
*
set_buffer_size
)(
struct
rpc_xprt
*
xprt
,
size_t
sndsize
,
size_t
rcvsize
);
int
(
*
reserve_xprt
)(
struct
rpc_task
*
task
);
void
(
*
release_xprt
)(
struct
rpc_xprt
*
xprt
,
struct
rpc_task
*
task
);
void
(
*
set_port
)(
struct
rpc_xprt
*
xprt
,
unsigned
short
port
);
void
(
*
connect
)(
struct
rpc_task
*
task
);
void
*
(
*
buf_alloc
)(
struct
rpc_task
*
task
,
size_t
size
);
void
(
*
buf_free
)(
struct
rpc_task
*
task
);
int
(
*
send_request
)(
struct
rpc_task
*
task
);
void
(
*
set_retrans_timeout
)(
struct
rpc_task
*
task
);
void
(
*
timer
)(
struct
rpc_task
*
task
);
...
...
@@ -253,6 +254,7 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to);
#define XPRT_LOCKED (0)
#define XPRT_CONNECTED (1)
#define XPRT_CONNECTING (2)
#define XPRT_CLOSE_WAIT (3)
static
inline
void
xprt_set_connected
(
struct
rpc_xprt
*
xprt
)
{
...
...
include/linux/writeback.h
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
mm/page-writeback.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/auth_gss/gss_krb5_mech.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/auth_gss/gss_spkm3_mech.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/auth_gss/gss_spkm3_seal.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/auth_gss/gss_spkm3_token.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/auth_gss/gss_spkm3_unseal.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/clnt.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/pmap_clnt.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/rpc_pipe.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/sched.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/sunrpc_syms.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/xdr.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/xprt.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
net/sunrpc/xprtsock.c
浏览文件 @
47853e7f
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录