Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
b7561e51
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b7561e51
编写于
8月 18, 2017
作者:
T
Trond Myklebust
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'writeback'
上级
55cfcd12
ce7c252a
变更
20
展开全部
隐藏空白更改
内联
并排
Showing
20 changed file
with
375 addition
and
407 deletion
+375
-407
fs/nfs/callback_proc.c
fs/nfs/callback_proc.c
+1
-1
fs/nfs/delegation.c
fs/nfs/delegation.c
+1
-1
fs/nfs/direct.c
fs/nfs/direct.c
+2
-2
fs/nfs/inode.c
fs/nfs/inode.c
+5
-5
fs/nfs/pagelist.c
fs/nfs/pagelist.c
+19
-48
fs/nfs/pnfs.c
fs/nfs/pnfs.c
+0
-41
fs/nfs/pnfs.h
fs/nfs/pnfs.h
+0
-2
fs/nfs/pnfs_nfs.c
fs/nfs/pnfs_nfs.c
+23
-14
fs/nfs/write.c
fs/nfs/write.c
+206
-234
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+3
-2
include/linux/nfs_page.h
include/linux/nfs_page.h
+1
-2
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+1
-1
include/linux/sunrpc/sched.h
include/linux/sunrpc/sched.h
+2
-0
include/linux/sunrpc/xprt.h
include/linux/sunrpc/xprt.h
+3
-0
net/sunrpc/backchannel_rqst.c
net/sunrpc/backchannel_rqst.c
+2
-2
net/sunrpc/svcsock.c
net/sunrpc/svcsock.c
+3
-3
net/sunrpc/xprt.c
net/sunrpc/xprt.c
+51
-4
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/rpc_rdma.c
+4
-4
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
+5
-2
net/sunrpc/xprtsock.c
net/sunrpc/xprtsock.c
+43
-39
未找到文件。
fs/nfs/callback_proc.c
浏览文件 @
b7561e51
...
...
@@ -51,7 +51,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
goto
out_iput
;
res
->
size
=
i_size_read
(
inode
);
res
->
change_attr
=
delegation
->
change_attr
;
if
(
nfs
i
->
nrequests
!=
0
)
if
(
nfs
_have_writebacks
(
inode
)
)
res
->
change_attr
++
;
res
->
ctime
=
inode
->
i_ctime
;
res
->
mtime
=
inode
->
i_mtime
;
...
...
fs/nfs/delegation.c
浏览文件 @
b7561e51
...
...
@@ -1089,7 +1089,7 @@ bool nfs4_delegation_flush_on_close(const struct inode *inode)
delegation
=
rcu_dereference
(
nfsi
->
delegation
);
if
(
delegation
==
NULL
||
!
(
delegation
->
type
&
FMODE_WRITE
))
goto
out
;
if
(
nfsi
->
nrequests
<
delegation
->
pagemod_limit
)
if
(
atomic_long_read
(
&
nfsi
->
nrequests
)
<
delegation
->
pagemod_limit
)
ret
=
false
;
out:
rcu_read_unlock
();
...
...
fs/nfs/direct.c
浏览文件 @
b7561e51
...
...
@@ -616,13 +616,13 @@ nfs_direct_write_scan_commit_list(struct inode *inode,
struct
list_head
*
list
,
struct
nfs_commit_info
*
cinfo
)
{
spin_lock
(
&
cinfo
->
inode
->
i_lock
);
mutex_lock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
#ifdef CONFIG_NFS_V4_1
if
(
cinfo
->
ds
!=
NULL
&&
cinfo
->
ds
->
nwritten
!=
0
)
NFS_SERVER
(
inode
)
->
pnfs_curr_ld
->
recover_commit_reqs
(
list
,
cinfo
);
#endif
nfs_scan_commit_list
(
&
cinfo
->
mds
->
list
,
list
,
cinfo
,
0
);
spin_unlock
(
&
cinfo
->
inode
->
i_lock
);
mutex_unlock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
}
static
void
nfs_direct_write_reschedule
(
struct
nfs_direct_req
*
dreq
)
...
...
fs/nfs/inode.c
浏览文件 @
b7561e51
...
...
@@ -1285,7 +1285,6 @@ static bool nfs_file_has_buffered_writers(struct nfs_inode *nfsi)
static
unsigned
long
nfs_wcc_update_inode
(
struct
inode
*
inode
,
struct
nfs_fattr
*
fattr
)
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
unsigned
long
ret
=
0
;
if
((
fattr
->
valid
&
NFS_ATTR_FATTR_PRECHANGE
)
...
...
@@ -1315,7 +1314,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
if
((
fattr
->
valid
&
NFS_ATTR_FATTR_PRESIZE
)
&&
(
fattr
->
valid
&
NFS_ATTR_FATTR_SIZE
)
&&
i_size_read
(
inode
)
==
nfs_size_to_loff_t
(
fattr
->
pre_size
)
&&
nfsi
->
nrequests
==
0
)
{
&&
!
nfs_have_writebacks
(
inode
)
)
{
i_size_write
(
inode
,
nfs_size_to_loff_t
(
fattr
->
size
));
ret
|=
NFS_INO_INVALID_ATTR
;
}
...
...
@@ -1823,7 +1822,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if
(
new_isize
!=
cur_isize
)
{
/* Do we perhaps have any outstanding writes, or has
* the file grown beyond our last write? */
if
(
nfsi
->
nrequests
==
0
||
new_isize
>
cur_isize
)
{
if
(
!
nfs_have_writebacks
(
inode
)
||
new_isize
>
cur_isize
)
{
i_size_write
(
inode
,
new_isize
);
if
(
!
have_writers
)
invalid
|=
NFS_INO_INVALID_ATTR
|
NFS_INO_INVALID_DATA
;
...
...
@@ -2012,10 +2011,11 @@ static void init_once(void *foo)
INIT_LIST_HEAD
(
&
nfsi
->
access_cache_entry_lru
);
INIT_LIST_HEAD
(
&
nfsi
->
access_cache_inode_lru
);
INIT_LIST_HEAD
(
&
nfsi
->
commit_info
.
list
);
nfsi
->
nrequests
=
0
;
nfsi
->
commit_info
.
ncommit
=
0
;
atomic_long_set
(
&
nfsi
->
nrequests
,
0
)
;
atomic_long_set
(
&
nfsi
->
commit_info
.
ncommit
,
0
)
;
atomic_set
(
&
nfsi
->
commit_info
.
rpcs_out
,
0
);
init_rwsem
(
&
nfsi
->
rmdir_sem
);
mutex_init
(
&
nfsi
->
commit_mutex
);
nfs4_init_once
(
nfsi
);
}
...
...
fs/nfs/pagelist.c
浏览文件 @
b7561e51
...
...
@@ -134,19 +134,14 @@ EXPORT_SYMBOL_GPL(nfs_async_iocounter_wait);
/*
* nfs_page_group_lock - lock the head of the page group
* @req - request in group that is to be locked
* @nonblock - if true don't block waiting for lock
*
* this lock must be held if modifying the page group list
* this lock must be held when traversing or modifying the page
* group list
*
* return 0 on success, < 0 on error: -EDELAY if nonblocking or the
* result from wait_on_bit_lock
*
* NOTE: calling with nonblock=false should always have set the
* lock bit (see fs/buffer.c and other uses of wait_on_bit_lock
* with TASK_UNINTERRUPTIBLE), so there is no need to check the result.
* return 0 on success, < 0 on error
*/
int
nfs_page_group_lock
(
struct
nfs_page
*
req
,
bool
nonblock
)
nfs_page_group_lock
(
struct
nfs_page
*
req
)
{
struct
nfs_page
*
head
=
req
->
wb_head
;
...
...
@@ -155,35 +150,10 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock)
if
(
!
test_and_set_bit
(
PG_HEADLOCK
,
&
head
->
wb_flags
))
return
0
;
if
(
!
nonblock
)
{
set_bit
(
PG_CONTENDED1
,
&
head
->
wb_flags
);
smp_mb__after_atomic
();
return
wait_on_bit_lock
(
&
head
->
wb_flags
,
PG_HEADLOCK
,
TASK_UNINTERRUPTIBLE
);
}
return
-
EAGAIN
;
}
/*
* nfs_page_group_lock_wait - wait for the lock to clear, but don't grab it
* @req - a request in the group
*
* This is a blocking call to wait for the group lock to be cleared.
*/
void
nfs_page_group_lock_wait
(
struct
nfs_page
*
req
)
{
struct
nfs_page
*
head
=
req
->
wb_head
;
WARN_ON_ONCE
(
head
!=
head
->
wb_head
);
if
(
!
test_bit
(
PG_HEADLOCK
,
&
head
->
wb_flags
))
return
;
set_bit
(
PG_CONTENDED1
,
&
head
->
wb_flags
);
smp_mb__after_atomic
();
wait_on_bit
(
&
head
->
wb_flags
,
PG_HEADLOCK
,
TASK_UNINTERRUPTIBLE
);
return
wait_on_bit_lock
(
&
head
->
wb_flags
,
PG_HEADLOCK
,
TASK_UNINTERRUPTIBLE
);
}
/*
...
...
@@ -246,7 +216,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit)
{
bool
ret
;
nfs_page_group_lock
(
req
,
false
);
nfs_page_group_lock
(
req
);
ret
=
nfs_page_group_sync_on_bit_locked
(
req
,
bit
);
nfs_page_group_unlock
(
req
);
...
...
@@ -288,9 +258,7 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
inode
=
page_file_mapping
(
req
->
wb_page
)
->
host
;
set_bit
(
PG_INODE_REF
,
&
req
->
wb_flags
);
kref_get
(
&
req
->
wb_kref
);
spin_lock
(
&
inode
->
i_lock
);
NFS_I
(
inode
)
->
nrequests
++
;
spin_unlock
(
&
inode
->
i_lock
);
atomic_long_inc
(
&
NFS_I
(
inode
)
->
nrequests
);
}
}
}
...
...
@@ -306,14 +274,11 @@ static void
nfs_page_group_destroy
(
struct
kref
*
kref
)
{
struct
nfs_page
*
req
=
container_of
(
kref
,
struct
nfs_page
,
wb_kref
);
struct
nfs_page
*
head
=
req
->
wb_head
;
struct
nfs_page
*
tmp
,
*
next
;
/* subrequests must release the ref on the head request */
if
(
req
->
wb_head
!=
req
)
nfs_release_request
(
req
->
wb_head
);
if
(
!
nfs_page_group_sync_on_bit
(
req
,
PG_TEARDOWN
))
return
;
goto
out
;
tmp
=
req
;
do
{
...
...
@@ -324,6 +289,10 @@ nfs_page_group_destroy(struct kref *kref)
nfs_free_request
(
tmp
);
tmp
=
next
;
}
while
(
tmp
!=
req
);
out:
/* subrequests must release the ref on the head request */
if
(
head
!=
req
)
nfs_release_request
(
head
);
}
/**
...
...
@@ -465,6 +434,7 @@ void nfs_release_request(struct nfs_page *req)
{
kref_put
(
&
req
->
wb_kref
,
nfs_page_group_destroy
);
}
EXPORT_SYMBOL_GPL
(
nfs_release_request
);
/**
* nfs_wait_on_request - Wait for a request to complete.
...
...
@@ -483,6 +453,7 @@ nfs_wait_on_request(struct nfs_page *req)
return
wait_on_bit_io
(
&
req
->
wb_flags
,
PG_BUSY
,
TASK_UNINTERRUPTIBLE
);
}
EXPORT_SYMBOL_GPL
(
nfs_wait_on_request
);
/*
* nfs_generic_pg_test - determine if requests can be coalesced
...
...
@@ -1036,7 +1007,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
unsigned
int
bytes_left
=
0
;
unsigned
int
offset
,
pgbase
;
nfs_page_group_lock
(
req
,
false
);
nfs_page_group_lock
(
req
);
subreq
=
req
;
bytes_left
=
subreq
->
wb_bytes
;
...
...
@@ -1058,7 +1029,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
if
(
mirror
->
pg_recoalesce
)
return
0
;
/* retry add_request for this subreq */
nfs_page_group_lock
(
req
,
false
);
nfs_page_group_lock
(
req
);
continue
;
}
...
...
@@ -1155,7 +1126,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
for
(
midx
=
0
;
midx
<
desc
->
pg_mirror_count
;
midx
++
)
{
if
(
midx
)
{
nfs_page_group_lock
(
req
,
false
);
nfs_page_group_lock
(
req
);
/* find the last request */
for
(
lastreq
=
req
->
wb_head
;
...
...
fs/nfs/pnfs.c
浏览文件 @
b7561e51
...
...
@@ -529,47 +529,6 @@ pnfs_put_lseg(struct pnfs_layout_segment *lseg)
}
EXPORT_SYMBOL_GPL
(
pnfs_put_lseg
);
static
void
pnfs_free_lseg_async_work
(
struct
work_struct
*
work
)
{
struct
pnfs_layout_segment
*
lseg
;
struct
pnfs_layout_hdr
*
lo
;
lseg
=
container_of
(
work
,
struct
pnfs_layout_segment
,
pls_work
);
lo
=
lseg
->
pls_layout
;
pnfs_free_lseg
(
lseg
);
pnfs_put_layout_hdr
(
lo
);
}
static
void
pnfs_free_lseg_async
(
struct
pnfs_layout_segment
*
lseg
)
{
INIT_WORK
(
&
lseg
->
pls_work
,
pnfs_free_lseg_async_work
);
schedule_work
(
&
lseg
->
pls_work
);
}
void
pnfs_put_lseg_locked
(
struct
pnfs_layout_segment
*
lseg
)
{
if
(
!
lseg
)
return
;
assert_spin_locked
(
&
lseg
->
pls_layout
->
plh_inode
->
i_lock
);
dprintk
(
"%s: lseg %p ref %d valid %d
\n
"
,
__func__
,
lseg
,
atomic_read
(
&
lseg
->
pls_refcount
),
test_bit
(
NFS_LSEG_VALID
,
&
lseg
->
pls_flags
));
if
(
atomic_dec_and_test
(
&
lseg
->
pls_refcount
))
{
struct
pnfs_layout_hdr
*
lo
=
lseg
->
pls_layout
;
if
(
test_bit
(
NFS_LSEG_VALID
,
&
lseg
->
pls_flags
))
return
;
pnfs_layout_remove_lseg
(
lo
,
lseg
);
if
(
!
pnfs_cache_lseg_for_layoutreturn
(
lo
,
lseg
))
{
pnfs_get_layout_hdr
(
lo
);
pnfs_free_lseg_async
(
lseg
);
}
}
}
/*
* is l2 fully contained in l1?
* start1 end1
...
...
fs/nfs/pnfs.h
浏览文件 @
b7561e51
...
...
@@ -67,7 +67,6 @@ struct pnfs_layout_segment {
u32
pls_seq
;
unsigned
long
pls_flags
;
struct
pnfs_layout_hdr
*
pls_layout
;
struct
work_struct
pls_work
;
};
enum
pnfs_try_status
{
...
...
@@ -230,7 +229,6 @@ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync);
/* pnfs.c */
void
pnfs_get_layout_hdr
(
struct
pnfs_layout_hdr
*
lo
);
void
pnfs_put_lseg
(
struct
pnfs_layout_segment
*
lseg
);
void
pnfs_put_lseg_locked
(
struct
pnfs_layout_segment
*
lseg
);
void
set_pnfs_layoutdriver
(
struct
nfs_server
*
,
const
struct
nfs_fh
*
,
struct
nfs_fsinfo
*
);
void
unset_pnfs_layoutdriver
(
struct
nfs_server
*
);
...
...
fs/nfs/pnfs_nfs.c
浏览文件 @
b7561e51
...
...
@@ -83,7 +83,7 @@ pnfs_generic_clear_request_commit(struct nfs_page *req,
}
out:
nfs_request_remove_commit_list
(
req
,
cinfo
);
pnfs_put_lseg
_locked
(
freeme
);
pnfs_put_lseg
(
freeme
);
}
EXPORT_SYMBOL_GPL
(
pnfs_generic_clear_request_commit
);
...
...
@@ -91,21 +91,30 @@ static int
pnfs_generic_transfer_commit_list
(
struct
list_head
*
src
,
struct
list_head
*
dst
,
struct
nfs_commit_info
*
cinfo
,
int
max
)
{
struct
nfs_page
*
req
,
*
tmp
;
struct
nfs_page
*
req
;
int
ret
=
0
;
list_for_each_entry_safe
(
req
,
tmp
,
src
,
wb_list
)
{
if
(
!
nfs_lock_request
(
req
))
continue
;
while
(
!
list_empty
(
src
)
)
{
req
=
list_first_entry
(
src
,
struct
nfs_page
,
wb_list
);
kref_get
(
&
req
->
wb_kref
);
if
(
cond_resched_lock
(
&
cinfo
->
inode
->
i_lock
))
list_safe_reset_next
(
req
,
tmp
,
wb_list
);
if
(
!
nfs_lock_request
(
req
))
{
int
status
;
mutex_unlock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
status
=
nfs_wait_on_request
(
req
);
nfs_release_request
(
req
);
mutex_lock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
if
(
status
<
0
)
break
;
continue
;
}
nfs_request_remove_commit_list
(
req
,
cinfo
);
clear_bit
(
PG_COMMIT_TO_DS
,
&
req
->
wb_flags
);
nfs_list_add_request
(
req
,
dst
);
ret
++
;
if
((
ret
==
max
)
&&
!
cinfo
->
dreq
)
break
;
cond_resched
();
}
return
ret
;
}
...
...
@@ -119,7 +128,7 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
struct
list_head
*
dst
=
&
bucket
->
committing
;
int
ret
;
lockdep_assert_held
(
&
cinfo
->
inode
->
i_lock
);
lockdep_assert_held
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
ret
=
pnfs_generic_transfer_commit_list
(
src
,
dst
,
cinfo
,
max
);
if
(
ret
)
{
cinfo
->
ds
->
nwritten
-=
ret
;
...
...
@@ -127,7 +136,7 @@ pnfs_generic_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
if
(
bucket
->
clseg
==
NULL
)
bucket
->
clseg
=
pnfs_get_lseg
(
bucket
->
wlseg
);
if
(
list_empty
(
src
))
{
pnfs_put_lseg
_locked
(
bucket
->
wlseg
);
pnfs_put_lseg
(
bucket
->
wlseg
);
bucket
->
wlseg
=
NULL
;
}
}
...
...
@@ -142,7 +151,7 @@ int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo,
{
int
i
,
rv
=
0
,
cnt
;
lockdep_assert_held
(
&
cinfo
->
inode
->
i_lock
);
lockdep_assert_held
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
for
(
i
=
0
;
i
<
cinfo
->
ds
->
nbuckets
&&
max
!=
0
;
i
++
)
{
cnt
=
pnfs_generic_scan_ds_commit_list
(
&
cinfo
->
ds
->
buckets
[
i
],
cinfo
,
max
);
...
...
@@ -162,7 +171,7 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
int
nwritten
;
int
i
;
lockdep_assert_held
(
&
cinfo
->
inode
->
i_lock
);
lockdep_assert_held
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
restart:
for
(
i
=
0
,
b
=
cinfo
->
ds
->
buckets
;
i
<
cinfo
->
ds
->
nbuckets
;
i
++
,
b
++
)
{
nwritten
=
pnfs_generic_transfer_commit_list
(
&
b
->
written
,
...
...
@@ -953,12 +962,12 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,
struct
list_head
*
list
;
struct
pnfs_commit_bucket
*
buckets
;
spin_lock
(
&
cinfo
->
inode
->
i_lock
);
mutex_lock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
buckets
=
cinfo
->
ds
->
buckets
;
list
=
&
buckets
[
ds_commit_idx
].
written
;
if
(
list_empty
(
list
))
{
if
(
!
pnfs_is_valid_lseg
(
lseg
))
{
spin_unlock
(
&
cinfo
->
inode
->
i_lock
);
mutex_unlock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
cinfo
->
completion_ops
->
resched_write
(
cinfo
,
req
);
return
;
}
...
...
@@ -975,7 +984,7 @@ pnfs_layout_mark_request_commit(struct nfs_page *req,
cinfo
->
ds
->
nwritten
++
;
nfs_request_add_commit_list_locked
(
req
,
list
,
cinfo
);
spin_unlock
(
&
cinfo
->
inode
->
i_lock
);
mutex_unlock
(
&
NFS_I
(
cinfo
->
inode
)
->
commit_mutex
);
nfs_mark_page_unstable
(
req
->
wb_page
,
cinfo
);
}
EXPORT_SYMBOL_GPL
(
pnfs_layout_mark_request_commit
);
...
...
fs/nfs/write.c
浏览文件 @
b7561e51
此差异已折叠。
点击以展开。
include/linux/nfs_fs.h
浏览文件 @
b7561e51
...
...
@@ -154,7 +154,7 @@ struct nfs_inode {
*/
__be32
cookieverf
[
2
];
unsigned
long
nrequests
;
atomic_long_t
nrequests
;
struct
nfs_mds_commit_info
commit_info
;
/* Open contexts for shared mmap writes */
...
...
@@ -163,6 +163,7 @@ struct nfs_inode {
/* Readers: in-flight sillydelete RPC calls */
/* Writers: rmdir */
struct
rw_semaphore
rmdir_sem
;
struct
mutex
commit_mutex
;
#if IS_ENABLED(CONFIG_NFS_V4)
struct
nfs4_cached_acl
*
nfs4_acl
;
...
...
@@ -510,7 +511,7 @@ extern void nfs_commit_free(struct nfs_commit_data *data);
static
inline
int
nfs_have_writebacks
(
struct
inode
*
inode
)
{
return
NFS_I
(
inode
)
->
nrequests
!=
0
;
return
atomic_long_read
(
&
NFS_I
(
inode
)
->
nrequests
)
!=
0
;
}
/*
...
...
include/linux/nfs_page.h
浏览文件 @
b7561e51
...
...
@@ -139,8 +139,7 @@ extern size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
extern
int
nfs_wait_on_request
(
struct
nfs_page
*
);
extern
void
nfs_unlock_request
(
struct
nfs_page
*
req
);
extern
void
nfs_unlock_and_release_request
(
struct
nfs_page
*
);
extern
int
nfs_page_group_lock
(
struct
nfs_page
*
,
bool
);
extern
void
nfs_page_group_lock_wait
(
struct
nfs_page
*
);
extern
int
nfs_page_group_lock
(
struct
nfs_page
*
);
extern
void
nfs_page_group_unlock
(
struct
nfs_page
*
);
extern
bool
nfs_page_group_sync_on_bit
(
struct
nfs_page
*
,
unsigned
int
);
extern
bool
nfs_async_iocounter_wait
(
struct
rpc_task
*
,
struct
nfs_lock_context
*
);
...
...
include/linux/nfs_xdr.h
浏览文件 @
b7561e51
...
...
@@ -1476,7 +1476,7 @@ struct nfs_pgio_header {
struct
nfs_mds_commit_info
{
atomic_t
rpcs_out
;
unsigned
long
ncommit
;
atomic_long_t
ncommit
;
struct
list_head
list
;
};
...
...
include/linux/sunrpc/sched.h
浏览文件 @
b7561e51
...
...
@@ -139,6 +139,8 @@ struct rpc_task_setup {
#define RPC_TASK_RUNNING 0
#define RPC_TASK_QUEUED 1
#define RPC_TASK_ACTIVE 2
#define RPC_TASK_MSG_RECV 3
#define RPC_TASK_MSG_RECV_WAIT 4
#define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
#define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
...
...
include/linux/sunrpc/xprt.h
浏览文件 @
b7561e51
...
...
@@ -232,6 +232,7 @@ struct rpc_xprt {
*/
spinlock_t
transport_lock
;
/* lock transport info */
spinlock_t
reserve_lock
;
/* lock slot table */
spinlock_t
recv_lock
;
/* lock receive list */
u32
xid
;
/* Next XID value to use */
struct
rpc_task
*
snd_task
;
/* Task blocked in send */
struct
svc_xprt
*
bc_xprt
;
/* NFSv4.1 backchannel */
...
...
@@ -372,6 +373,8 @@ void xprt_write_space(struct rpc_xprt *xprt);
void
xprt_adjust_cwnd
(
struct
rpc_xprt
*
xprt
,
struct
rpc_task
*
task
,
int
result
);
struct
rpc_rqst
*
xprt_lookup_rqst
(
struct
rpc_xprt
*
xprt
,
__be32
xid
);
void
xprt_complete_rqst
(
struct
rpc_task
*
task
,
int
copied
);
void
xprt_pin_rqst
(
struct
rpc_rqst
*
req
);
void
xprt_unpin_rqst
(
struct
rpc_rqst
*
req
);
void
xprt_release_rqst_cong
(
struct
rpc_task
*
task
);
void
xprt_disconnect_done
(
struct
rpc_xprt
*
xprt
);
void
xprt_force_disconnect
(
struct
rpc_xprt
*
xprt
);
...
...
net/sunrpc/backchannel_rqst.c
浏览文件 @
b7561e51
...
...
@@ -171,10 +171,10 @@ int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs)
/*
* Add the temporary list to the backchannel preallocation list
*/
spin_lock
_bh
(
&
xprt
->
bc_pa_lock
);
spin_lock
(
&
xprt
->
bc_pa_lock
);
list_splice
(
&
tmp_list
,
&
xprt
->
bc_pa_list
);
xprt_inc_alloc_count
(
xprt
,
min_reqs
);
spin_unlock
_bh
(
&
xprt
->
bc_pa_lock
);
spin_unlock
(
&
xprt
->
bc_pa_lock
);
dprintk
(
"RPC: setup backchannel transport done
\n
"
);
return
0
;
...
...
net/sunrpc/svcsock.c
浏览文件 @
b7561e51
...
...
@@ -1001,7 +1001,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
if
(
!
bc_xprt
)
return
-
EAGAIN
;
spin_lock
_bh
(
&
bc_xprt
->
transport
_lock
);
spin_lock
(
&
bc_xprt
->
recv
_lock
);
req
=
xprt_lookup_rqst
(
bc_xprt
,
xid
);
if
(
!
req
)
goto
unlock_notfound
;
...
...
@@ -1019,7 +1019,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
memcpy
(
dst
->
iov_base
,
src
->
iov_base
,
src
->
iov_len
);
xprt_complete_rqst
(
req
->
rq_task
,
rqstp
->
rq_arg
.
len
);
rqstp
->
rq_arg
.
len
=
0
;
spin_unlock
_bh
(
&
bc_xprt
->
transport
_lock
);
spin_unlock
(
&
bc_xprt
->
recv
_lock
);
return
0
;
unlock_notfound:
printk
(
KERN_NOTICE
...
...
@@ -1028,7 +1028,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
__func__
,
ntohl
(
calldir
),
bc_xprt
,
ntohl
(
xid
));
unlock_eagain:
spin_unlock
_bh
(
&
bc_xprt
->
transport
_lock
);
spin_unlock
(
&
bc_xprt
->
recv
_lock
);
return
-
EAGAIN
;
}
...
...
net/sunrpc/xprt.c
浏览文件 @
b7561e51
...
...
@@ -844,6 +844,48 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
}
EXPORT_SYMBOL_GPL
(
xprt_lookup_rqst
);
/**
* xprt_pin_rqst - Pin a request on the transport receive list
* @req: Request to pin
*
* Caller must ensure this is atomic with the call to xprt_lookup_rqst()
* so should be holding the xprt transport lock.
*/
void
xprt_pin_rqst
(
struct
rpc_rqst
*
req
)
{
set_bit
(
RPC_TASK_MSG_RECV
,
&
req
->
rq_task
->
tk_runstate
);
}
/**
* xprt_unpin_rqst - Unpin a request on the transport receive list
* @req: Request to pin
*
* Caller should be holding the xprt transport lock.
*/
void
xprt_unpin_rqst
(
struct
rpc_rqst
*
req
)
{
struct
rpc_task
*
task
=
req
->
rq_task
;
clear_bit
(
RPC_TASK_MSG_RECV
,
&
task
->
tk_runstate
);
if
(
test_bit
(
RPC_TASK_MSG_RECV_WAIT
,
&
task
->
tk_runstate
))
wake_up_bit
(
&
task
->
tk_runstate
,
RPC_TASK_MSG_RECV
);
}
static
void
xprt_wait_on_pinned_rqst
(
struct
rpc_rqst
*
req
)
__must_hold
(
&
req
->
rq_xprt
->
recv_lock
)
{
struct
rpc_task
*
task
=
req
->
rq_task
;
if
(
task
&&
test_bit
(
RPC_TASK_MSG_RECV
,
&
task
->
tk_runstate
))
{
spin_unlock
(
&
req
->
rq_xprt
->
recv_lock
);
set_bit
(
RPC_TASK_MSG_RECV_WAIT
,
&
task
->
tk_runstate
);
wait_on_bit
(
&
task
->
tk_runstate
,
RPC_TASK_MSG_RECV
,
TASK_UNINTERRUPTIBLE
);
clear_bit
(
RPC_TASK_MSG_RECV_WAIT
,
&
task
->
tk_runstate
);
spin_lock
(
&
req
->
rq_xprt
->
recv_lock
);
}
}
static
void
xprt_update_rtt
(
struct
rpc_task
*
task
)
{
struct
rpc_rqst
*
req
=
task
->
tk_rqstp
;
...
...
@@ -966,13 +1008,13 @@ void xprt_transmit(struct rpc_task *task)
/*
* Add to the list only if we're expecting a reply
*/
spin_lock_bh
(
&
xprt
->
transport_lock
);
/* Update the softirq receive buffer */
memcpy
(
&
req
->
rq_private_buf
,
&
req
->
rq_rcv_buf
,
sizeof
(
req
->
rq_private_buf
));
/* Add request to the receive list */
spin_lock
(
&
xprt
->
recv_lock
);
list_add_tail
(
&
req
->
rq_list
,
&
xprt
->
recv
);
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
xprt_reset_majortimeo
(
req
);
/* Turn off autodisconnect */
del_singleshot_timer_sync
(
&
xprt
->
timer
);
...
...
@@ -1287,12 +1329,16 @@ void xprt_release(struct rpc_task *task)
task
->
tk_ops
->
rpc_count_stats
(
task
,
task
->
tk_calldata
);
else
if
(
task
->
tk_client
)
rpc_count_iostats
(
task
,
task
->
tk_client
->
cl_metrics
);
spin_lock
(
&
xprt
->
recv_lock
);
if
(
!
list_empty
(
&
req
->
rq_list
))
{
list_del
(
&
req
->
rq_list
);
xprt_wait_on_pinned_rqst
(
req
);
}
spin_unlock
(
&
xprt
->
recv_lock
);
spin_lock_bh
(
&
xprt
->
transport_lock
);
xprt
->
ops
->
release_xprt
(
xprt
,
task
);
if
(
xprt
->
ops
->
release_request
)
xprt
->
ops
->
release_request
(
task
);
if
(
!
list_empty
(
&
req
->
rq_list
))
list_del
(
&
req
->
rq_list
);
xprt
->
last_used
=
jiffies
;
xprt_schedule_autodisconnect
(
xprt
);
spin_unlock_bh
(
&
xprt
->
transport_lock
);
...
...
@@ -1318,6 +1364,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net)
spin_lock_init
(
&
xprt
->
transport_lock
);
spin_lock_init
(
&
xprt
->
reserve_lock
);
spin_lock_init
(
&
xprt
->
recv_lock
);
INIT_LIST_HEAD
(
&
xprt
->
free
);
INIT_LIST_HEAD
(
&
xprt
->
recv
);
...
...
net/sunrpc/xprtrdma/rpc_rdma.c
浏览文件 @
b7561e51
...
...
@@ -1051,7 +1051,7 @@ rpcrdma_reply_handler(struct work_struct *work)
* RPC completion while holding the transport lock to ensure
* the rep, rqst, and rq_task pointers remain stable.
*/
spin_lock
_bh
(
&
xprt
->
transport
_lock
);
spin_lock
(
&
xprt
->
recv
_lock
);
rqst
=
xprt_lookup_rqst
(
xprt
,
headerp
->
rm_xid
);
if
(
!
rqst
)
goto
out_norqst
;
...
...
@@ -1136,7 +1136,7 @@ rpcrdma_reply_handler(struct work_struct *work)
xprt_release_rqst_cong
(
rqst
->
rq_task
);
xprt_complete_rqst
(
rqst
->
rq_task
,
status
);
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
dprintk
(
"RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)
\n
"
,
__func__
,
xprt
,
rqst
,
status
);
return
;
...
...
@@ -1187,12 +1187,12 @@ rpcrdma_reply_handler(struct work_struct *work)
r_xprt
->
rx_stats
.
bad_reply_count
++
;
goto
out
;
/* The req was still available, but by the time the
transport
_lock
/* The req was still available, but by the time the
recv
_lock
* was acquired, the rqst and task had been released. Thus the RPC
* has already been terminated.
*/
out_norqst:
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
rpcrdma_buffer_put
(
req
);
dprintk
(
"RPC: %s: race, no rqst left for req %p
\n
"
,
__func__
,
req
);
...
...
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
浏览文件 @
b7561e51
...
...
@@ -52,7 +52,7 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
if
(
src
->
iov_len
<
24
)
goto
out_shortreply
;
spin_lock
_bh
(
&
xprt
->
transport
_lock
);
spin_lock
(
&
xprt
->
recv
_lock
);
req
=
xprt_lookup_rqst
(
xprt
,
xid
);
if
(
!
req
)
goto
out_notfound
;
...
...
@@ -69,17 +69,20 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
else
if
(
credits
>
r_xprt
->
rx_buf
.
rb_bc_max_requests
)
credits
=
r_xprt
->
rx_buf
.
rb_bc_max_requests
;
spin_lock_bh
(
&
xprt
->
transport_lock
);
cwnd
=
xprt
->
cwnd
;
xprt
->
cwnd
=
credits
<<
RPC_CWNDSHIFT
;
if
(
xprt
->
cwnd
>
cwnd
)
xprt_release_rqst_cong
(
req
->
rq_task
);
spin_unlock_bh
(
&
xprt
->
transport_lock
);
ret
=
0
;
xprt_complete_rqst
(
req
->
rq_task
,
rcvbuf
->
len
);
rcvbuf
->
len
=
0
;
out_unlock:
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
out:
return
ret
;
...
...
net/sunrpc/xprtsock.c
浏览文件 @
b7561e51
...
...
@@ -969,10 +969,12 @@ static void xs_local_data_read_skb(struct rpc_xprt *xprt,
return
;
/* Look up and lock the request corresponding to the given XID */
spin_lock
_bh
(
&
xprt
->
transport
_lock
);
spin_lock
(
&
xprt
->
recv
_lock
);
rovr
=
xprt_lookup_rqst
(
xprt
,
*
xp
);
if
(
!
rovr
)
goto
out_unlock
;
xprt_pin_rqst
(
rovr
);
spin_unlock
(
&
xprt
->
recv_lock
);
task
=
rovr
->
rq_task
;
copied
=
rovr
->
rq_private_buf
.
buflen
;
...
...
@@ -981,13 +983,16 @@ static void xs_local_data_read_skb(struct rpc_xprt *xprt,
if
(
xs_local_copy_to_xdr
(
&
rovr
->
rq_private_buf
,
skb
))
{
dprintk
(
"RPC: sk_buff copy failed
\n
"
);
goto
out_unlock
;
spin_lock
(
&
xprt
->
recv_lock
);
goto
out_unpin
;
}
spin_lock
(
&
xprt
->
recv_lock
);
xprt_complete_rqst
(
task
,
copied
);
out_unpin:
xprt_unpin_rqst
(
rovr
);
out_unlock:
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
}
static
void
xs_local_data_receive
(
struct
sock_xprt
*
transport
)
...
...
@@ -1050,10 +1055,12 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt,
return
;
/* Look up and lock the request corresponding to the given XID */
spin_lock
_bh
(
&
xprt
->
transport
_lock
);
spin_lock
(
&
xprt
->
recv
_lock
);
rovr
=
xprt_lookup_rqst
(
xprt
,
*
xp
);
if
(
!
rovr
)
goto
out_unlock
;
xprt_pin_rqst
(
rovr
);
spin_unlock
(
&
xprt
->
recv_lock
);
task
=
rovr
->
rq_task
;
if
((
copied
=
rovr
->
rq_private_buf
.
buflen
)
>
repsize
)
...
...
@@ -1062,16 +1069,21 @@ static void xs_udp_data_read_skb(struct rpc_xprt *xprt,
/* Suck it into the iovec, verify checksum if not done by hw. */
if
(
csum_partial_copy_to_xdr
(
&
rovr
->
rq_private_buf
,
skb
))
{
__UDPX_INC_STATS
(
sk
,
UDP_MIB_INERRORS
);
goto
out_unlock
;
spin_lock
(
&
xprt
->
recv_lock
);
goto
out_unpin
;
}
__UDPX_INC_STATS
(
sk
,
UDP_MIB_INDATAGRAMS
);
spin_lock_bh
(
&
xprt
->
transport_lock
);
xprt_adjust_cwnd
(
xprt
,
task
,
copied
);
spin_unlock_bh
(
&
xprt
->
transport_lock
);
spin_lock
(
&
xprt
->
recv_lock
);
xprt_complete_rqst
(
task
,
copied
);
out_unpin:
xprt_unpin_rqst
(
rovr
);
out_unlock:
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
}
static
void
xs_udp_data_receive
(
struct
sock_xprt
*
transport
)
...
...
@@ -1277,25 +1289,12 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt,
}
len
=
desc
->
count
;
if
(
len
>
transport
->
tcp_reclen
-
transport
->
tcp_offset
)
{
struct
xdr_skb_reader
my_desc
;
len
=
transport
->
tcp_reclen
-
transport
->
tcp_offset
;
memcpy
(
&
my_desc
,
desc
,
sizeof
(
my_desc
));
my_desc
.
count
=
len
;
r
=
xdr_partial_copy_from_skb
(
rcvbuf
,
transport
->
tcp_copied
,
&
my_desc
,
xdr_skb_read_bits
);
desc
->
count
-=
r
;
desc
->
offset
+=
r
;
}
else
r
=
xdr_partial_copy_from_skb
(
rcvbuf
,
transport
->
tcp_copied
,
if
(
len
>
transport
->
tcp_reclen
-
transport
->
tcp_offset
)
desc
->
count
=
transport
->
tcp_reclen
-
transport
->
tcp_offset
;
r
=
xdr_partial_copy_from_skb
(
rcvbuf
,
transport
->
tcp_copied
,
desc
,
xdr_skb_read_bits
);
if
(
r
>
0
)
{
transport
->
tcp_copied
+=
r
;
transport
->
tcp_offset
+=
r
;
}
if
(
r
!=
len
)
{
if
(
desc
->
count
)
{
/* Error when copying to the receive buffer,
* usually because we weren't able to allocate
* additional buffer pages. All we can do now
...
...
@@ -1315,6 +1314,10 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt,
return
;
}
transport
->
tcp_copied
+=
r
;
transport
->
tcp_offset
+=
r
;
desc
->
count
=
len
-
r
;
dprintk
(
"RPC: XID %08x read %zd bytes
\n
"
,
ntohl
(
transport
->
tcp_xid
),
r
);
dprintk
(
"RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, "
...
...
@@ -1343,21 +1346,24 @@ static inline int xs_tcp_read_reply(struct rpc_xprt *xprt,
dprintk
(
"RPC: read reply XID %08x
\n
"
,
ntohl
(
transport
->
tcp_xid
));
/* Find and lock the request corresponding to this xid */
spin_lock
_bh
(
&
xprt
->
transport
_lock
);
spin_lock
(
&
xprt
->
recv
_lock
);
req
=
xprt_lookup_rqst
(
xprt
,
transport
->
tcp_xid
);
if
(
!
req
)
{
dprintk
(
"RPC: XID %08x request not found!
\n
"
,
ntohl
(
transport
->
tcp_xid
));
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
spin_unlock
(
&
xprt
->
recv
_lock
);
return
-
1
;
}
xprt_pin_rqst
(
req
);
spin_unlock
(
&
xprt
->
recv_lock
);
xs_tcp_read_common
(
xprt
,
desc
,
req
);
spin_lock
(
&
xprt
->
recv_lock
);
if
(
!
(
transport
->
tcp_flags
&
TCP_RCV_COPY_DATA
))
xprt_complete_rqst
(
req
->
rq_task
,
transport
->
tcp_copied
);
spin_unlock
_bh
(
&
xprt
->
transport
_lock
);
xprt_unpin_rqst
(
req
);
spin_unlock
(
&
xprt
->
recv
_lock
);
return
0
;
}
...
...
@@ -1376,11 +1382,9 @@ static int xs_tcp_read_callback(struct rpc_xprt *xprt,
container_of
(
xprt
,
struct
sock_xprt
,
xprt
);
struct
rpc_rqst
*
req
;
/* Look up and lock the request corresponding to the given XID */
spin_lock_bh
(
&
xprt
->
transport_lock
);
/* Look up the request corresponding to the given XID */
req
=
xprt_lookup_bc_request
(
xprt
,
transport
->
tcp_xid
);
if
(
req
==
NULL
)
{
spin_unlock_bh
(
&
xprt
->
transport_lock
);
printk
(
KERN_WARNING
"Callback slot table overflowed
\n
"
);
xprt_force_disconnect
(
xprt
);
return
-
1
;
...
...
@@ -1391,7 +1395,6 @@ static int xs_tcp_read_callback(struct rpc_xprt *xprt,
if
(
!
(
transport
->
tcp_flags
&
TCP_RCV_COPY_DATA
))
xprt_complete_bc_request
(
req
,
transport
->
tcp_copied
);
spin_unlock_bh
(
&
xprt
->
transport_lock
);
return
0
;
}
...
...
@@ -1516,6 +1519,7 @@ static void xs_tcp_data_receive(struct sock_xprt *transport)
.
arg
.
data
=
xprt
,
};
unsigned
long
total
=
0
;
int
loop
;
int
read
=
0
;
mutex_lock
(
&
transport
->
recv_mutex
);
...
...
@@ -1524,20 +1528,20 @@ static void xs_tcp_data_receive(struct sock_xprt *transport)
goto
out
;
/* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
for
(
;;
)
{
for
(
loop
=
0
;
loop
<
64
;
loop
++
)
{
lock_sock
(
sk
);
read
=
tcp_read_sock
(
sk
,
&
rd_desc
,
xs_tcp_data_recv
);
if
(
read
<=
0
)
{
clear_bit
(
XPRT_SOCK_DATA_READY
,
&
transport
->
sock_state
);
release_sock
(
sk
);
if
(
!
test_bit
(
XPRT_SOCK_DATA_READY
,
&
transport
->
sock_state
))
break
;
}
else
{
release_sock
(
sk
);
total
+=
read
;
break
;
}
release_sock
(
sk
);
total
+=
read
;
rd_desc
.
count
=
65536
;
}
if
(
test_bit
(
XPRT_SOCK_DATA_READY
,
&
transport
->
sock_state
))
queue_work
(
xprtiod_workqueue
,
&
transport
->
recv_worker
);
out:
mutex_unlock
(
&
transport
->
recv_mutex
);
trace_xs_tcp_data_ready
(
xprt
,
read
,
total
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录