summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/erofs/data.c25
-rw-r--r--fs/erofs/inode.c2
-rw-r--r--fs/erofs/internal.h18
-rw-r--r--fs/erofs/xattr.c13
-rw-r--r--fs/erofs/zmap.c4
5 files changed, 16 insertions, 46 deletions
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index 0136ea117934..28eda71bb1a9 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -51,25 +51,19 @@ static struct bio *erofs_grab_raw_bio(struct super_block *sb,
51 return bio; 51 return bio;
52} 52}
53 53
54/* prio -- true is used for dir */ 54struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
55struct page *__erofs_get_meta_page(struct super_block *sb,
56 erofs_blk_t blkaddr, bool prio, bool nofail)
57{ 55{
58 struct inode *const bd_inode = sb->s_bdev->bd_inode; 56 struct inode *const bd_inode = sb->s_bdev->bd_inode;
59 struct address_space *const mapping = bd_inode->i_mapping; 57 struct address_space *const mapping = bd_inode->i_mapping;
60 /* prefer retrying in the allocator to blindly looping below */ 58 const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS);
61 const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS) |
62 (nofail ? __GFP_NOFAIL : 0);
63 unsigned int io_retries = nofail ? EROFS_IO_MAX_RETRIES_NOFAIL : 0;
64 struct page *page; 59 struct page *page;
65 int err; 60 int err;
66 61
67repeat: 62repeat:
68 page = find_or_create_page(mapping, blkaddr, gfp); 63 page = find_or_create_page(mapping, blkaddr, gfp);
69 if (!page) { 64 if (!page)
70 DBG_BUGON(nofail);
71 return ERR_PTR(-ENOMEM); 65 return ERR_PTR(-ENOMEM);
72 } 66
73 DBG_BUGON(!PageLocked(page)); 67 DBG_BUGON(!PageLocked(page));
74 68
75 if (!PageUptodate(page)) { 69 if (!PageUptodate(page)) {
@@ -82,14 +76,11 @@ repeat:
82 goto err_out; 76 goto err_out;
83 } 77 }
84 78
85 __submit_bio(bio, REQ_OP_READ, 79 __submit_bio(bio, REQ_OP_READ, REQ_META);
86 REQ_META | (prio ? REQ_PRIO : 0));
87
88 lock_page(page); 80 lock_page(page);
89 81
90 /* this page has been truncated by others */ 82 /* this page has been truncated by others */
91 if (page->mapping != mapping) { 83 if (page->mapping != mapping) {
92unlock_repeat:
93 unlock_page(page); 84 unlock_page(page);
94 put_page(page); 85 put_page(page);
95 goto repeat; 86 goto repeat;
@@ -97,10 +88,6 @@ unlock_repeat:
97 88
98 /* more likely a read error */ 89 /* more likely a read error */
99 if (!PageUptodate(page)) { 90 if (!PageUptodate(page)) {
100 if (io_retries) {
101 --io_retries;
102 goto unlock_repeat;
103 }
104 err = -EIO; 91 err = -EIO;
105 goto err_out; 92 goto err_out;
106 } 93 }
@@ -251,7 +238,7 @@ submit_bio_retry:
251 238
252 DBG_BUGON(map.m_plen > PAGE_SIZE); 239 DBG_BUGON(map.m_plen > PAGE_SIZE);
253 240
254 ipage = erofs_get_meta_page(inode->i_sb, blknr, 0); 241 ipage = erofs_get_meta_page(inode->i_sb, blknr);
255 242
256 if (IS_ERR(ipage)) { 243 if (IS_ERR(ipage)) {
257 err = PTR_ERR(ipage); 244 err = PTR_ERR(ipage);
diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
index 770f3259c862..8d496adbeaea 100644
--- a/fs/erofs/inode.c
+++ b/fs/erofs/inode.c
@@ -182,7 +182,7 @@ static int fill_inode(struct inode *inode, int isdir)
182 debugln("%s, reading inode nid %llu at %u of blkaddr %u", 182 debugln("%s, reading inode nid %llu at %u of blkaddr %u",
183 __func__, vi->nid, ofs, blkaddr); 183 __func__, vi->nid, ofs, blkaddr);
184 184
185 page = erofs_get_meta_page(inode->i_sb, blkaddr, isdir); 185 page = erofs_get_meta_page(inode->i_sb, blkaddr);
186 186
187 if (IS_ERR(page)) { 187 if (IS_ERR(page)) {
188 errln("failed to get inode (nid: %llu) page, err %ld", 188 errln("failed to get inode (nid: %llu) page, err %ld",
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 000ea92b36a3..90c62fb5f80d 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -258,8 +258,6 @@ static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
258#error erofs cannot be used in this platform 258#error erofs cannot be used in this platform
259#endif 259#endif
260 260
261#define EROFS_IO_MAX_RETRIES_NOFAIL 5
262
263#define ROOT_NID(sb) ((sb)->root_nid) 261#define ROOT_NID(sb) ((sb)->root_nid)
264 262
265#define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ) 263#define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ)
@@ -418,24 +416,10 @@ static inline void __submit_bio(struct bio *bio, unsigned int op,
418 submit_bio(bio); 416 submit_bio(bio);
419} 417}
420 418
421struct page *__erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr, 419struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr);
422 bool prio, bool nofail);
423
424static inline struct page *erofs_get_meta_page(struct super_block *sb,
425 erofs_blk_t blkaddr, bool prio)
426{
427 return __erofs_get_meta_page(sb, blkaddr, prio, false);
428}
429 420
430int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int); 421int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int);
431 422
432static inline struct page *erofs_get_inline_page(struct inode *inode,
433 erofs_blk_t blkaddr)
434{
435 return erofs_get_meta_page(inode->i_sb, blkaddr,
436 S_ISDIR(inode->i_mode));
437}
438
439/* inode.c */ 423/* inode.c */
440static inline unsigned long erofs_inode_hash(erofs_nid_t nid) 424static inline unsigned long erofs_inode_hash(erofs_nid_t nid)
441{ 425{
diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c
index d5b7fe0bee45..dd445c81c41f 100644
--- a/fs/erofs/xattr.c
+++ b/fs/erofs/xattr.c
@@ -87,7 +87,7 @@ static int init_inode_xattrs(struct inode *inode)
87 it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize); 87 it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
88 it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize); 88 it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
89 89
90 it.page = erofs_get_inline_page(inode, it.blkaddr); 90 it.page = erofs_get_meta_page(sb, it.blkaddr);
91 if (IS_ERR(it.page)) { 91 if (IS_ERR(it.page)) {
92 ret = PTR_ERR(it.page); 92 ret = PTR_ERR(it.page);
93 goto out_unlock; 93 goto out_unlock;
@@ -117,8 +117,7 @@ static int init_inode_xattrs(struct inode *inode)
117 DBG_BUGON(it.ofs != EROFS_BLKSIZ); 117 DBG_BUGON(it.ofs != EROFS_BLKSIZ);
118 xattr_iter_end(&it, atomic_map); 118 xattr_iter_end(&it, atomic_map);
119 119
120 it.page = erofs_get_meta_page(sb, ++it.blkaddr, 120 it.page = erofs_get_meta_page(sb, ++it.blkaddr);
121 S_ISDIR(inode->i_mode));
122 if (IS_ERR(it.page)) { 121 if (IS_ERR(it.page)) {
123 kfree(vi->xattr_shared_xattrs); 122 kfree(vi->xattr_shared_xattrs);
124 vi->xattr_shared_xattrs = NULL; 123 vi->xattr_shared_xattrs = NULL;
@@ -168,7 +167,7 @@ static inline int xattr_iter_fixup(struct xattr_iter *it)
168 167
169 it->blkaddr += erofs_blknr(it->ofs); 168 it->blkaddr += erofs_blknr(it->ofs);
170 169
171 it->page = erofs_get_meta_page(it->sb, it->blkaddr, false); 170 it->page = erofs_get_meta_page(it->sb, it->blkaddr);
172 if (IS_ERR(it->page)) { 171 if (IS_ERR(it->page)) {
173 int err = PTR_ERR(it->page); 172 int err = PTR_ERR(it->page);
174 173
@@ -199,7 +198,7 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
199 it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs); 198 it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs);
200 it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs); 199 it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
201 200
202 it->page = erofs_get_inline_page(inode, it->blkaddr); 201 it->page = erofs_get_meta_page(inode->i_sb, it->blkaddr);
203 if (IS_ERR(it->page)) 202 if (IS_ERR(it->page))
204 return PTR_ERR(it->page); 203 return PTR_ERR(it->page);
205 204
@@ -401,7 +400,7 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
401 if (i) 400 if (i)
402 xattr_iter_end(&it->it, true); 401 xattr_iter_end(&it->it, true);
403 402
404 it->it.page = erofs_get_meta_page(sb, blkaddr, false); 403 it->it.page = erofs_get_meta_page(sb, blkaddr);
405 if (IS_ERR(it->it.page)) 404 if (IS_ERR(it->it.page))
406 return PTR_ERR(it->it.page); 405 return PTR_ERR(it->it.page);
407 406
@@ -623,7 +622,7 @@ static int shared_listxattr(struct listxattr_iter *it)
623 if (i) 622 if (i)
624 xattr_iter_end(&it->it, true); 623 xattr_iter_end(&it->it, true);
625 624
626 it->it.page = erofs_get_meta_page(sb, blkaddr, false); 625 it->it.page = erofs_get_meta_page(sb, blkaddr);
627 if (IS_ERR(it->it.page)) 626 if (IS_ERR(it->it.page))
628 return PTR_ERR(it->it.page); 627 return PTR_ERR(it->it.page);
629 628
diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
index 30a5171637d7..9c141f145508 100644
--- a/fs/erofs/zmap.c
+++ b/fs/erofs/zmap.c
@@ -50,7 +50,7 @@ static int fill_inode_lazy(struct inode *inode)
50 50
51 pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + 51 pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
52 vi->xattr_isize, 8); 52 vi->xattr_isize, 8);
53 page = erofs_get_meta_page(sb, erofs_blknr(pos), false); 53 page = erofs_get_meta_page(sb, erofs_blknr(pos));
54 if (IS_ERR(page)) { 54 if (IS_ERR(page)) {
55 err = PTR_ERR(page); 55 err = PTR_ERR(page);
56 goto out_unlock; 56 goto out_unlock;
@@ -127,7 +127,7 @@ static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m,
127 put_page(mpage); 127 put_page(mpage);
128 } 128 }
129 129
130 mpage = erofs_get_meta_page(sb, eblk, false); 130 mpage = erofs_get_meta_page(sb, eblk);
131 if (IS_ERR(mpage)) { 131 if (IS_ERR(mpage)) {
132 map->mpage = NULL; 132 map->mpage = NULL;
133 return PTR_ERR(mpage); 133 return PTR_ERR(mpage);