Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
ec108d3c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
ec108d3c
编写于
1年前
作者:
A
Anna Schumaker
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
NFS: Convert readdir page array functions to use a folio
Signed-off-by:
N
Anna Schumaker
<
Anna.Schumaker@Netapp.com
>
上级
61f02e0a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
99 addition
and
102 deletion
+99
-102
fs/nfs/dir.c
fs/nfs/dir.c
+99
-102
未找到文件。
fs/nfs/dir.c
浏览文件 @
ec108d3c
...
...
@@ -55,7 +55,7 @@ static int nfs_closedir(struct inode *, struct file *);
static
int
nfs_readdir
(
struct
file
*
,
struct
dir_context
*
);
static
int
nfs_fsync_dir
(
struct
file
*
,
loff_t
,
loff_t
,
int
);
static
loff_t
nfs_llseek_dir
(
struct
file
*
,
loff_t
,
int
);
static
void
nfs_readdir_
free_folio
(
struct
folio
*
);
static
void
nfs_readdir_
clear_array
(
struct
folio
*
);
const
struct
file_operations
nfs_dir_operations
=
{
.
llseek
=
nfs_llseek_dir
,
...
...
@@ -67,7 +67,7 @@ const struct file_operations nfs_dir_operations = {
};
const
struct
address_space_operations
nfs_dir_aops
=
{
.
free_folio
=
nfs_readdir_
free_folio
,
.
free_folio
=
nfs_readdir_
clear_array
,
};
#define NFS_INIT_DTSIZE PAGE_SIZE
...
...
@@ -146,8 +146,8 @@ struct nfs_cache_array {
u64
change_attr
;
u64
last_cookie
;
unsigned
int
size
;
unsigned
char
page
_full
:
1
,
page
_is_eof
:
1
,
unsigned
char
folio
_full
:
1
,
folio
_is_eof
:
1
,
cookies_are_ordered
:
1
;
struct
nfs_cache_array_entry
array
[];
};
...
...
@@ -198,17 +198,17 @@ static void nfs_grow_dtsize(struct nfs_readdir_descriptor *desc)
nfs_set_dtsize
(
desc
,
desc
->
dtsize
<<
1
);
}
static
void
nfs_readdir_
page_init_array
(
struct
page
*
page
,
u64
last_cookie
,
u64
change_attr
)
static
void
nfs_readdir_
folio_init_array
(
struct
folio
*
folio
,
u64
last_cookie
,
u64
change_attr
)
{
struct
nfs_cache_array
*
array
;
array
=
kmap_local_
page
(
page
);
array
=
kmap_local_
folio
(
folio
,
0
);
array
->
change_attr
=
change_attr
;
array
->
last_cookie
=
last_cookie
;
array
->
size
=
0
;
array
->
page
_full
=
0
;
array
->
page
_is_eof
=
0
;
array
->
folio
_full
=
0
;
array
->
folio
_is_eof
=
0
;
array
->
cookies_are_ordered
=
1
;
kunmap_local
(
array
);
}
...
...
@@ -216,44 +216,39 @@ static void nfs_readdir_page_init_array(struct page *page, u64 last_cookie,
/*
* we are freeing strings created by nfs_add_to_readdir_array()
*/
static
void
nfs_readdir_clear_array
(
struct
page
*
page
)
static
void
nfs_readdir_clear_array
(
struct
folio
*
folio
)
{
struct
nfs_cache_array
*
array
;
unsigned
int
i
;
array
=
kmap_local_
page
(
page
);
array
=
kmap_local_
folio
(
folio
,
0
);
for
(
i
=
0
;
i
<
array
->
size
;
i
++
)
kfree
(
array
->
array
[
i
].
name
);
array
->
size
=
0
;
kunmap_local
(
array
);
}
static
void
nfs_readdir_free_folio
(
struct
folio
*
folio
)
static
void
nfs_readdir_folio_reinit_array
(
struct
folio
*
folio
,
u64
last_cookie
,
u64
change_attr
)
{
nfs_readdir_clear_array
(
&
folio
->
page
);
nfs_readdir_clear_array
(
folio
);
nfs_readdir_folio_init_array
(
folio
,
last_cookie
,
change_attr
);
}
static
void
nfs_readdir_page_reinit_array
(
struct
page
*
page
,
u64
last_cookie
,
u64
change_attr
)
{
nfs_readdir_clear_array
(
page
);
nfs_readdir_page_init_array
(
page
,
last_cookie
,
change_attr
);
}
static
struct
page
*
nfs_readdir_page_array_alloc
(
u64
last_cookie
,
gfp_t
gfp_flags
)
static
struct
folio
*
nfs_readdir_folio_array_alloc
(
u64
last_cookie
,
gfp_t
gfp_flags
)
{
struct
page
*
page
=
alloc_page
(
gfp_flags
);
if
(
page
)
nfs_readdir_
page_init_array
(
page
,
last_cookie
,
0
);
return
page
;
struct
folio
*
folio
=
folio_alloc
(
gfp_flags
,
0
);
if
(
folio
)
nfs_readdir_
folio_init_array
(
folio
,
last_cookie
,
0
);
return
folio
;
}
static
void
nfs_readdir_
page_array_free
(
struct
page
*
page
)
static
void
nfs_readdir_
folio_array_free
(
struct
folio
*
folio
)
{
if
(
page
)
{
nfs_readdir_clear_array
(
page
);
put_page
(
page
);
if
(
folio
)
{
nfs_readdir_clear_array
(
folio
);
folio_put
(
folio
);
}
}
...
...
@@ -264,13 +259,13 @@ static u64 nfs_readdir_array_index_cookie(struct nfs_cache_array *array)
static
void
nfs_readdir_array_set_eof
(
struct
nfs_cache_array
*
array
)
{
array
->
page
_is_eof
=
1
;
array
->
page
_full
=
1
;
array
->
folio
_is_eof
=
1
;
array
->
folio
_full
=
1
;
}
static
bool
nfs_readdir_array_is_full
(
struct
nfs_cache_array
*
array
)
{
return
array
->
page
_full
;
return
array
->
folio
_full
;
}
/*
...
...
@@ -302,16 +297,16 @@ static size_t nfs_readdir_array_maxentries(void)
*/
static
int
nfs_readdir_array_can_expand
(
struct
nfs_cache_array
*
array
)
{
if
(
array
->
page
_full
)
if
(
array
->
folio
_full
)
return
-
ENOSPC
;
if
(
array
->
size
==
nfs_readdir_array_maxentries
())
{
array
->
page
_full
=
1
;
array
->
folio
_full
=
1
;
return
-
ENOSPC
;
}
return
0
;
}
static
int
nfs_readdir_
page_array_append
(
struct
page
*
page
,
static
int
nfs_readdir_
folio_array_append
(
struct
folio
*
folio
,
const
struct
nfs_entry
*
entry
,
u64
*
cookie
)
{
...
...
@@ -322,7 +317,7 @@ static int nfs_readdir_page_array_append(struct page *page,
name
=
nfs_readdir_copy_name
(
entry
->
name
,
entry
->
len
);
array
=
kmap_atomic
(
page
);
array
=
kmap_atomic
(
folio_page
(
folio
,
0
)
);
if
(
!
name
)
goto
out
;
ret
=
nfs_readdir_array_can_expand
(
array
);
...
...
@@ -361,17 +356,17 @@ static int nfs_readdir_page_array_append(struct page *page,
* 127 readdir entries for a typical 64-bit system, that works out to a
* cache of ~ 33 million entries per directory.
*/
static
pgoff_t
nfs_readdir_
page
_cookie_hash
(
u64
cookie
)
static
pgoff_t
nfs_readdir_
folio
_cookie_hash
(
u64
cookie
)
{
if
(
cookie
==
0
)
return
0
;
return
hash_64
(
cookie
,
18
);
}
static
bool
nfs_readdir_
page_validate
(
struct
page
*
page
,
u64
last_cookie
,
u64
change_attr
)
static
bool
nfs_readdir_
folio_validate
(
struct
folio
*
folio
,
u64
last_cookie
,
u64
change_attr
)
{
struct
nfs_cache_array
*
array
=
kmap_local_
page
(
page
);
struct
nfs_cache_array
*
array
=
kmap_local_
folio
(
folio
,
0
);
int
ret
=
true
;
if
(
array
->
change_attr
!=
change_attr
)
...
...
@@ -382,81 +377,83 @@ static bool nfs_readdir_page_validate(struct page *page, u64 last_cookie,
return
ret
;
}
static
void
nfs_readdir_
page_unlock_and_put
(
struct
page
*
page
)
static
void
nfs_readdir_
folio_unlock_and_put
(
struct
folio
*
folio
)
{
unlock_page
(
page
);
put_page
(
page
);
folio_unlock
(
folio
);
folio_put
(
folio
);
}
static
void
nfs_readdir_
page_init_and_validate
(
struct
page
*
page
,
u64
cookie
,
u64
change_attr
)
static
void
nfs_readdir_
folio_init_and_validate
(
struct
folio
*
folio
,
u64
cookie
,
u64
change_attr
)
{
if
(
PageUptodate
(
page
))
{
if
(
nfs_readdir_
page_validate
(
page
,
cookie
,
change_attr
))
if
(
folio_test_uptodate
(
folio
))
{
if
(
nfs_readdir_
folio_validate
(
folio
,
cookie
,
change_attr
))
return
;
nfs_readdir_clear_array
(
page
);
nfs_readdir_clear_array
(
folio
);
}
nfs_readdir_
page_init_array
(
page
,
cookie
,
change_attr
);
SetPageUptodate
(
page
);
nfs_readdir_
folio_init_array
(
folio
,
cookie
,
change_attr
);
folio_mark_uptodate
(
folio
);
}
static
struct
page
*
nfs_readdir_page
_get_locked
(
struct
address_space
*
mapping
,
u64
cookie
,
u64
change_attr
)
static
struct
folio
*
nfs_readdir_folio
_get_locked
(
struct
address_space
*
mapping
,
u64
cookie
,
u64
change_attr
)
{
pgoff_t
index
=
nfs_readdir_
page
_cookie_hash
(
cookie
);
struct
page
*
page
;
pgoff_t
index
=
nfs_readdir_
folio
_cookie_hash
(
cookie
);
struct
folio
*
folio
;
page
=
grab_cache_page
(
mapping
,
index
);
if
(
!
page
)
folio
=
filemap_grab_folio
(
mapping
,
index
);
if
(
!
folio
)
return
NULL
;
nfs_readdir_
page_init_and_validate
(
page
,
cookie
,
change_attr
);
return
page
;
nfs_readdir_
folio_init_and_validate
(
folio
,
cookie
,
change_attr
);
return
folio
;
}
static
u64
nfs_readdir_
page_last_cookie
(
struct
page
*
page
)
static
u64
nfs_readdir_
folio_last_cookie
(
struct
folio
*
folio
)
{
struct
nfs_cache_array
*
array
;
u64
ret
;
array
=
kmap_local_
page
(
page
);
array
=
kmap_local_
folio
(
folio
,
0
);
ret
=
array
->
last_cookie
;
kunmap_local
(
array
);
return
ret
;
}
static
bool
nfs_readdir_
page_needs_filling
(
struct
page
*
page
)
static
bool
nfs_readdir_
folio_needs_filling
(
struct
folio
*
folio
)
{
struct
nfs_cache_array
*
array
;
bool
ret
;
array
=
kmap_local_
page
(
page
);
array
=
kmap_local_
folio
(
folio
,
0
);
ret
=
!
nfs_readdir_array_is_full
(
array
);
kunmap_local
(
array
);
return
ret
;
}
static
void
nfs_readdir_
page_set_eof
(
struct
page
*
page
)
static
void
nfs_readdir_
folio_set_eof
(
struct
folio
*
folio
)
{
struct
nfs_cache_array
*
array
;
array
=
kmap_local_
page
(
page
);
array
=
kmap_local_
folio
(
folio
,
0
);
nfs_readdir_array_set_eof
(
array
);
kunmap_local
(
array
);
}
static
struct
page
*
nfs_readdir_page
_get_next
(
struct
address_space
*
mapping
,
u64
cookie
,
u64
change_attr
)
static
struct
folio
*
nfs_readdir_folio
_get_next
(
struct
address_space
*
mapping
,
u64
cookie
,
u64
change_attr
)
{
pgoff_t
index
=
nfs_readdir_
page
_cookie_hash
(
cookie
);
struct
page
*
page
;
pgoff_t
index
=
nfs_readdir_
folio
_cookie_hash
(
cookie
);
struct
folio
*
folio
;
page
=
grab_cache_page_nowait
(
mapping
,
index
);
if
(
!
page
)
folio
=
__filemap_get_folio
(
mapping
,
index
,
FGP_LOCK
|
FGP_CREAT
|
FGP_NOFS
|
FGP_NOWAIT
,
mapping_gfp_mask
(
mapping
));
if
(
!
folio
)
return
NULL
;
nfs_readdir_
page_init_and_validate
(
page
,
cookie
,
change_attr
);
if
(
nfs_readdir_
page_last_cookie
(
page
)
!=
cookie
)
nfs_readdir_
page_reinit_array
(
page
,
cookie
,
change_attr
);
return
page
;
nfs_readdir_
folio_init_and_validate
(
folio
,
cookie
,
change_attr
);
if
(
nfs_readdir_
folio_last_cookie
(
folio
)
!=
cookie
)
nfs_readdir_
folio_reinit_array
(
folio
,
cookie
,
change_attr
);
return
folio
;
}
static
inline
...
...
@@ -481,7 +478,7 @@ bool nfs_readdir_use_cookie(const struct file *filp)
static
void
nfs_readdir_seek_next_array
(
struct
nfs_cache_array
*
array
,
struct
nfs_readdir_descriptor
*
desc
)
{
if
(
array
->
page
_full
)
{
if
(
array
->
folio
_full
)
{
desc
->
last_cookie
=
array
->
last_cookie
;
desc
->
current_index
+=
array
->
size
;
desc
->
cache_entry_index
=
0
;
...
...
@@ -506,7 +503,7 @@ static int nfs_readdir_search_for_pos(struct nfs_cache_array *array,
if
(
diff
<
0
)
goto
out_eof
;
if
(
diff
>=
array
->
size
)
{
if
(
array
->
page
_is_eof
)
if
(
array
->
folio
_is_eof
)
goto
out_eof
;
nfs_readdir_seek_next_array
(
array
,
desc
);
return
-
EAGAIN
;
...
...
@@ -554,7 +551,7 @@ static int nfs_readdir_search_for_cookie(struct nfs_cache_array *array,
}
}
check_eof:
if
(
array
->
page
_is_eof
)
{
if
(
array
->
folio
_is_eof
)
{
status
=
-
EBADCOOKIE
;
if
(
desc
->
dir_cookie
==
array
->
last_cookie
)
desc
->
eof
=
true
;
...
...
@@ -826,9 +823,9 @@ static int nfs_readdir_folio_filler(struct nfs_readdir_descriptor *desc,
u64
change_attr
)
{
struct
address_space
*
mapping
=
desc
->
file
->
f_mapping
;
struct
folio
*
folio
=
*
arrays
;
struct
folio
*
new
,
*
folio
=
*
arrays
;
struct
xdr_stream
stream
;
struct
page
*
scratch
,
*
new
;
struct
page
*
scratch
;
struct
xdr_buf
buf
;
u64
cookie
;
int
status
;
...
...
@@ -845,36 +842,36 @@ static int nfs_readdir_folio_filler(struct nfs_readdir_descriptor *desc,
if
(
status
!=
0
)
break
;
status
=
nfs_readdir_
page_array_append
(
folio_page
(
folio
,
0
)
,
entry
,
&
cookie
);
status
=
nfs_readdir_
folio_array_append
(
folio
,
entry
,
&
cookie
);
if
(
status
!=
-
ENOSPC
)
continue
;
if
(
folio
->
mapping
!=
mapping
)
{
if
(
!--
narrays
)
break
;
new
=
nfs_readdir_
page
_array_alloc
(
cookie
,
GFP_KERNEL
);
new
=
nfs_readdir_
folio
_array_alloc
(
cookie
,
GFP_KERNEL
);
if
(
!
new
)
break
;
arrays
++
;
*
arrays
=
folio
=
page_folio
(
new
)
;
*
arrays
=
folio
=
new
;
}
else
{
new
=
nfs_readdir_
page
_get_next
(
mapping
,
cookie
,
change_attr
);
new
=
nfs_readdir_
folio
_get_next
(
mapping
,
cookie
,
change_attr
);
if
(
!
new
)
break
;
if
(
folio
!=
*
arrays
)
nfs_readdir_
page_unlock_and_put
(
folio_page
(
folio
,
0
)
);
folio
=
page_folio
(
new
)
;
nfs_readdir_
folio_unlock_and_put
(
folio
);
folio
=
new
;
}
desc
->
folio_index_max
++
;
status
=
nfs_readdir_
page_array_append
(
folio_page
(
folio
,
0
)
,
entry
,
&
cookie
);
status
=
nfs_readdir_
folio_array_append
(
folio
,
entry
,
&
cookie
);
}
while
(
!
status
&&
!
entry
->
eof
);
switch
(
status
)
{
case
-
EBADCOOKIE
:
if
(
!
entry
->
eof
)
break
;
nfs_readdir_
page_set_eof
(
folio_page
(
folio
,
0
)
);
nfs_readdir_
folio_set_eof
(
folio
);
fallthrough
;
case
-
EAGAIN
:
status
=
0
;
...
...
@@ -888,7 +885,7 @@ static int nfs_readdir_folio_filler(struct nfs_readdir_descriptor *desc,
}
if
(
folio
!=
*
arrays
)
nfs_readdir_
page_unlock_and_put
(
folio_page
(
folio
,
0
)
);
nfs_readdir_
folio_unlock_and_put
(
folio
);
put_page
(
scratch
);
return
status
;
...
...
@@ -943,7 +940,7 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
entry
=
kzalloc
(
sizeof
(
*
entry
),
GFP_KERNEL
);
if
(
!
entry
)
return
-
ENOMEM
;
entry
->
cookie
=
nfs_readdir_
page_last_cookie
(
folio_page
(
folio
,
0
)
);
entry
->
cookie
=
nfs_readdir_
folio_last_cookie
(
folio
);
entry
->
fh
=
nfs_alloc_fhandle
();
entry
->
fattr
=
nfs_alloc_fattr_with_label
(
NFS_SERVER
(
inode
));
entry
->
server
=
NFS_SERVER
(
inode
);
...
...
@@ -966,7 +963,7 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
status
=
nfs_readdir_folio_filler
(
desc
,
entry
,
pages
,
pglen
,
arrays
,
narrays
,
change_attr
);
else
nfs_readdir_
page_set_eof
(
folio_page
(
folio
,
0
)
);
nfs_readdir_
folio_set_eof
(
folio
);
desc
->
buffer_fills
++
;
free_pages:
...
...
@@ -997,14 +994,14 @@ nfs_readdir_folio_get_cached(struct nfs_readdir_descriptor *desc)
struct
address_space
*
mapping
=
desc
->
file
->
f_mapping
;
u64
change_attr
=
inode_peek_iversion_raw
(
mapping
->
host
);
u64
cookie
=
desc
->
last_cookie
;
struct
page
*
page
;
struct
folio
*
folio
;
page
=
nfs_readdir_page
_get_locked
(
mapping
,
cookie
,
change_attr
);
if
(
!
page
)
folio
=
nfs_readdir_folio
_get_locked
(
mapping
,
cookie
,
change_attr
);
if
(
!
folio
)
return
NULL
;
if
(
desc
->
clear_cache
&&
!
nfs_readdir_
page_needs_filling
(
page
))
nfs_readdir_
page_reinit_array
(
page
,
cookie
,
change_attr
);
return
page_folio
(
page
)
;
if
(
desc
->
clear_cache
&&
!
nfs_readdir_
folio_needs_filling
(
folio
))
nfs_readdir_
folio_reinit_array
(
folio
,
cookie
,
change_attr
);
return
folio
;
}
/*
...
...
@@ -1021,7 +1018,7 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
desc
->
folio
=
nfs_readdir_folio_get_cached
(
desc
);
if
(
!
desc
->
folio
)
return
-
ENOMEM
;
if
(
nfs_readdir_
page_needs_filling
(
folio_page
(
desc
->
folio
,
0
)
))
{
if
(
nfs_readdir_
folio_needs_filling
(
desc
->
folio
))
{
/* Grow the dtsize if we had to go back for more pages */
if
(
desc
->
folio_index
==
desc
->
folio_index_max
)
nfs_grow_dtsize
(
desc
);
...
...
@@ -1115,7 +1112,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
break
;
}
}
if
(
array
->
page
_is_eof
)
if
(
array
->
folio
_is_eof
)
desc
->
eof
=
!
desc
->
eob
;
kunmap_local
(
array
);
...
...
@@ -1148,7 +1145,7 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
arrays
=
kcalloc
(
sz
,
sizeof
(
*
arrays
),
GFP_KERNEL
);
if
(
!
arrays
)
goto
out
;
arrays
[
0
]
=
page_folio
(
nfs_readdir_page_array_alloc
(
desc
->
dir_cookie
,
GFP_KERNEL
)
);
arrays
[
0
]
=
nfs_readdir_folio_array_alloc
(
desc
->
dir_cookie
,
GFP_KERNEL
);
if
(
!
arrays
[
0
])
goto
out
;
...
...
@@ -1185,7 +1182,7 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
}
out_free:
for
(
i
=
0
;
i
<
sz
&&
arrays
[
i
];
i
++
)
nfs_readdir_
page_array_free
(
folio_page
(
arrays
[
i
],
0
)
);
nfs_readdir_
folio_array_free
(
arrays
[
i
]
);
out:
if
(
!
nfs_readdir_use_cookie
(
desc
->
file
))
nfs_readdir_rewind_search
(
desc
);
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
新手
引导
客服
返回
顶部