2
2
/*
3
3
* Copyright (C) 2017-2018 HUAWEI, Inc.
4
4
* https://www.huawei.com/
5
+ * Copyright (C) 2022, Alibaba Cloud
5
6
*/
6
7
#include "xattr.h"
7
8
@@ -86,25 +87,26 @@ static struct erofs_dirent *find_target_dirent(struct erofs_qstr *name,
86
87
return ERR_PTR (- ENOENT );
87
88
}
88
89
89
- static struct page * find_target_block_classic (struct inode * dir ,
90
- struct erofs_qstr * name ,
91
- int * _ndirents )
90
+ static void * find_target_block_classic (struct erofs_buf * target ,
91
+ struct inode * dir ,
92
+ struct erofs_qstr * name ,
93
+ int * _ndirents )
92
94
{
93
95
unsigned int startprfx , endprfx ;
94
96
int head , back ;
95
- struct address_space * const mapping = dir -> i_mapping ;
96
- struct page * candidate = ERR_PTR (- ENOENT );
97
+ void * candidate = ERR_PTR (- ENOENT );
97
98
98
99
startprfx = endprfx = 0 ;
99
100
head = 0 ;
100
101
back = erofs_inode_datablocks (dir ) - 1 ;
101
102
102
103
while (head <= back ) {
103
104
const int mid = head + (back - head ) / 2 ;
104
- struct page * page = read_mapping_page (mapping , mid , NULL );
105
+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER ;
106
+ struct erofs_dirent * de ;
105
107
106
- if (! IS_ERR ( page )) {
107
- struct erofs_dirent * de = kmap_atomic ( page );
108
+ de = erofs_bread ( & buf , dir , mid , EROFS_KMAP );
109
+ if (! IS_ERR ( de )) {
108
110
const int nameoff = nameoff_from_disk (de -> nameoff ,
109
111
EROFS_BLKSIZ );
110
112
const int ndirents = nameoff / sizeof (* de );
@@ -113,13 +115,12 @@ static struct page *find_target_block_classic(struct inode *dir,
113
115
struct erofs_qstr dname ;
114
116
115
117
if (!ndirents ) {
116
- kunmap_atomic (de );
117
- put_page (page );
118
+ erofs_put_metabuf (& buf );
118
119
erofs_err (dir -> i_sb ,
119
120
"corrupted dir block %d @ nid %llu" ,
120
121
mid , EROFS_I (dir )-> nid );
121
122
DBG_BUGON (1 );
122
- page = ERR_PTR (- EFSCORRUPTED );
123
+ de = ERR_PTR (- EFSCORRUPTED );
123
124
goto out ;
124
125
}
125
126
@@ -135,7 +136,6 @@ static struct page *find_target_block_classic(struct inode *dir,
135
136
136
137
/* string comparison without already matched prefix */
137
138
diff = erofs_dirnamecmp (name , & dname , & matched );
138
- kunmap_atomic (de );
139
139
140
140
if (!diff ) {
141
141
* _ndirents = 0 ;
@@ -145,11 +145,12 @@ static struct page *find_target_block_classic(struct inode *dir,
145
145
startprfx = matched ;
146
146
147
147
if (!IS_ERR (candidate ))
148
- put_page (candidate );
149
- candidate = page ;
148
+ erofs_put_metabuf (target );
149
+ * target = buf ;
150
+ candidate = de ;
150
151
* _ndirents = ndirents ;
151
152
} else {
152
- put_page ( page );
153
+ erofs_put_metabuf ( & buf );
153
154
154
155
back = mid - 1 ;
155
156
endprfx = matched ;
@@ -158,8 +159,8 @@ static struct page *find_target_block_classic(struct inode *dir,
158
159
}
159
160
out : /* free if the candidate is valid */
160
161
if (!IS_ERR (candidate ))
161
- put_page ( candidate );
162
- return page ;
162
+ erofs_put_metabuf ( target );
163
+ return de ;
163
164
}
164
165
return candidate ;
165
166
}
@@ -169,8 +170,7 @@ int erofs_namei(struct inode *dir,
169
170
erofs_nid_t * nid , unsigned int * d_type )
170
171
{
171
172
int ndirents ;
172
- struct page * page ;
173
- void * data ;
173
+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER ;
174
174
struct erofs_dirent * de ;
175
175
struct erofs_qstr qn ;
176
176
@@ -181,26 +181,20 @@ int erofs_namei(struct inode *dir,
181
181
qn .end = name -> name + name -> len ;
182
182
183
183
ndirents = 0 ;
184
- page = find_target_block_classic (dir , & qn , & ndirents );
185
184
186
- if (IS_ERR (page ))
187
- return PTR_ERR (page );
185
+ de = find_target_block_classic (& buf , dir , & qn , & ndirents );
186
+ if (IS_ERR (de ))
187
+ return PTR_ERR (de );
188
188
189
- data = kmap_atomic (page );
190
189
/* the target page has been mapped */
191
190
if (ndirents )
192
- de = find_target_dirent (& qn , data , EROFS_BLKSIZ , ndirents );
193
- else
194
- de = (struct erofs_dirent * )data ;
191
+ de = find_target_dirent (& qn , (u8 * )de , EROFS_BLKSIZ , ndirents );
195
192
196
193
if (!IS_ERR (de )) {
197
194
* nid = le64_to_cpu (de -> nid );
198
195
* d_type = de -> file_type ;
199
196
}
200
-
201
- kunmap_atomic (data );
202
- put_page (page );
203
-
197
+ erofs_put_metabuf (& buf );
204
198
return PTR_ERR_OR_ZERO (de );
205
199
}
206
200
0 commit comments