Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.20 420 lines 9.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/drivers/staging/erofs/data.c 4 * 5 * Copyright (C) 2017-2018 HUAWEI, Inc. 6 * http://www.huawei.com/ 7 * Created by Gao Xiang <gaoxiang25@huawei.com> 8 * 9 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file COPYING in the main directory of the Linux 11 * distribution for more details. 12 */ 13#include "internal.h" 14#include <linux/prefetch.h> 15 16#include <trace/events/erofs.h> 17 18static inline void read_endio(struct bio *bio) 19{ 20 int i; 21 struct bio_vec *bvec; 22 const blk_status_t err = bio->bi_status; 23 24 bio_for_each_segment_all(bvec, bio, i) { 25 struct page *page = bvec->bv_page; 26 27 /* page is already locked */ 28 DBG_BUGON(PageUptodate(page)); 29 30 if (unlikely(err)) 31 SetPageError(page); 32 else 33 SetPageUptodate(page); 34 35 unlock_page(page); 36 /* page could be reclaimed now */ 37 } 38 bio_put(bio); 39} 40 41/* prio -- true is used for dir */ 42struct page *__erofs_get_meta_page(struct super_block *sb, 43 erofs_blk_t blkaddr, bool prio, bool nofail) 44{ 45 struct inode *const bd_inode = sb->s_bdev->bd_inode; 46 struct address_space *const mapping = bd_inode->i_mapping; 47 /* prefer retrying in the allocator to blindly looping below */ 48 const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS) | 49 (nofail ? __GFP_NOFAIL : 0); 50 unsigned int io_retries = nofail ? EROFS_IO_MAX_RETRIES_NOFAIL : 0; 51 struct page *page; 52 int err; 53 54repeat: 55 page = find_or_create_page(mapping, blkaddr, gfp); 56 if (unlikely(page == NULL)) { 57 DBG_BUGON(nofail); 58 return ERR_PTR(-ENOMEM); 59 } 60 DBG_BUGON(!PageLocked(page)); 61 62 if (!PageUptodate(page)) { 63 struct bio *bio; 64 65 bio = erofs_grab_bio(sb, blkaddr, 1, read_endio, nofail); 66 if (IS_ERR(bio)) { 67 DBG_BUGON(nofail); 68 err = PTR_ERR(bio); 69 goto err_out; 70 } 71 72 err = bio_add_page(bio, page, PAGE_SIZE, 0); 73 if (unlikely(err != PAGE_SIZE)) { 74 err = -EFAULT; 75 goto err_out; 76 } 77 78 __submit_bio(bio, REQ_OP_READ, 79 REQ_META | (prio ? REQ_PRIO : 0)); 80 81 lock_page(page); 82 83 /* this page has been truncated by others */ 84 if (unlikely(page->mapping != mapping)) { 85unlock_repeat: 86 unlock_page(page); 87 put_page(page); 88 goto repeat; 89 } 90 91 /* more likely a read error */ 92 if (unlikely(!PageUptodate(page))) { 93 if (io_retries) { 94 --io_retries; 95 goto unlock_repeat; 96 } 97 err = -EIO; 98 goto err_out; 99 } 100 } 101 return page; 102 103err_out: 104 unlock_page(page); 105 put_page(page); 106 return ERR_PTR(err); 107} 108 109static int erofs_map_blocks_flatmode(struct inode *inode, 110 struct erofs_map_blocks *map, 111 int flags) 112{ 113 int err = 0; 114 erofs_blk_t nblocks, lastblk; 115 u64 offset = map->m_la; 116 struct erofs_vnode *vi = EROFS_V(inode); 117 118 trace_erofs_map_blocks_flatmode_enter(inode, map, flags); 119 120 nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE); 121 lastblk = nblocks - is_inode_layout_inline(inode); 122 123 if (unlikely(offset >= inode->i_size)) { 124 /* leave out-of-bound access unmapped */ 125 map->m_flags = 0; 126 map->m_plen = 0; 127 goto out; 128 } 129 130 /* there is no hole in flatmode */ 131 map->m_flags = EROFS_MAP_MAPPED; 132 133 if (offset < blknr_to_addr(lastblk)) { 134 map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la; 135 map->m_plen = blknr_to_addr(lastblk) - offset; 136 } else if (is_inode_layout_inline(inode)) { 137 /* 2 - inode inline B: inode, [xattrs], inline last blk... */ 138 struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 139 140 map->m_pa = iloc(sbi, vi->nid) + vi->inode_isize + 141 vi->xattr_isize + erofs_blkoff(map->m_la); 142 map->m_plen = inode->i_size - offset; 143 144 /* inline data should locate in one meta block */ 145 if (erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE) { 146 DBG_BUGON(1); 147 err = -EIO; 148 goto err_out; 149 } 150 151 map->m_flags |= EROFS_MAP_META; 152 } else { 153 errln("internal error @ nid: %llu (size %llu), m_la 0x%llx", 154 vi->nid, inode->i_size, map->m_la); 155 DBG_BUGON(1); 156 err = -EIO; 157 goto err_out; 158 } 159 160out: 161 map->m_llen = map->m_plen; 162 163err_out: 164 trace_erofs_map_blocks_flatmode_exit(inode, map, flags, 0); 165 return err; 166} 167 168#ifdef CONFIG_EROFS_FS_ZIP 169extern int z_erofs_map_blocks_iter(struct inode *, 170 struct erofs_map_blocks *, struct page **, int); 171#endif 172 173int erofs_map_blocks_iter(struct inode *inode, 174 struct erofs_map_blocks *map, 175 struct page **mpage_ret, int flags) 176{ 177 /* by default, reading raw data never use erofs_map_blocks_iter */ 178 if (unlikely(!is_inode_layout_compression(inode))) { 179 if (*mpage_ret != NULL) 180 put_page(*mpage_ret); 181 *mpage_ret = NULL; 182 183 return erofs_map_blocks(inode, map, flags); 184 } 185 186#ifdef CONFIG_EROFS_FS_ZIP 187 return z_erofs_map_blocks_iter(inode, map, mpage_ret, flags); 188#else 189 /* data compression is not available */ 190 return -ENOTSUPP; 191#endif 192} 193 194int erofs_map_blocks(struct inode *inode, 195 struct erofs_map_blocks *map, int flags) 196{ 197 if (unlikely(is_inode_layout_compression(inode))) { 198 struct page *mpage = NULL; 199 int err; 200 201 err = erofs_map_blocks_iter(inode, map, &mpage, flags); 202 if (mpage != NULL) 203 put_page(mpage); 204 return err; 205 } 206 return erofs_map_blocks_flatmode(inode, map, flags); 207} 208 209static inline struct bio *erofs_read_raw_page( 210 struct bio *bio, 211 struct address_space *mapping, 212 struct page *page, 213 erofs_off_t *last_block, 214 unsigned int nblocks, 215 bool ra) 216{ 217 struct inode *inode = mapping->host; 218 erofs_off_t current_block = (erofs_off_t)page->index; 219 int err; 220 221 DBG_BUGON(!nblocks); 222 223 if (PageUptodate(page)) { 224 err = 0; 225 goto has_updated; 226 } 227 228 if (cleancache_get_page(page) == 0) { 229 err = 0; 230 SetPageUptodate(page); 231 goto has_updated; 232 } 233 234 /* note that for readpage case, bio also equals to NULL */ 235 if (bio != NULL && 236 /* not continuous */ 237 *last_block + 1 != current_block) { 238submit_bio_retry: 239 __submit_bio(bio, REQ_OP_READ, 0); 240 bio = NULL; 241 } 242 243 if (bio == NULL) { 244 struct erofs_map_blocks map = { 245 .m_la = blknr_to_addr(current_block), 246 }; 247 erofs_blk_t blknr; 248 unsigned int blkoff; 249 250 err = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); 251 if (unlikely(err)) 252 goto err_out; 253 254 /* zero out the holed page */ 255 if (unlikely(!(map.m_flags & EROFS_MAP_MAPPED))) { 256 zero_user_segment(page, 0, PAGE_SIZE); 257 SetPageUptodate(page); 258 259 /* imply err = 0, see erofs_map_blocks */ 260 goto has_updated; 261 } 262 263 /* for RAW access mode, m_plen must be equal to m_llen */ 264 DBG_BUGON(map.m_plen != map.m_llen); 265 266 blknr = erofs_blknr(map.m_pa); 267 blkoff = erofs_blkoff(map.m_pa); 268 269 /* deal with inline page */ 270 if (map.m_flags & EROFS_MAP_META) { 271 void *vsrc, *vto; 272 struct page *ipage; 273 274 DBG_BUGON(map.m_plen > PAGE_SIZE); 275 276 ipage = erofs_get_meta_page(inode->i_sb, blknr, 0); 277 278 if (IS_ERR(ipage)) { 279 err = PTR_ERR(ipage); 280 goto err_out; 281 } 282 283 vsrc = kmap_atomic(ipage); 284 vto = kmap_atomic(page); 285 memcpy(vto, vsrc + blkoff, map.m_plen); 286 memset(vto + map.m_plen, 0, PAGE_SIZE - map.m_plen); 287 kunmap_atomic(vto); 288 kunmap_atomic(vsrc); 289 flush_dcache_page(page); 290 291 SetPageUptodate(page); 292 /* TODO: could we unlock the page earlier? */ 293 unlock_page(ipage); 294 put_page(ipage); 295 296 /* imply err = 0, see erofs_map_blocks */ 297 goto has_updated; 298 } 299 300 /* pa must be block-aligned for raw reading */ 301 DBG_BUGON(erofs_blkoff(map.m_pa)); 302 303 /* max # of continuous pages */ 304 if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) 305 nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE); 306 if (nblocks > BIO_MAX_PAGES) 307 nblocks = BIO_MAX_PAGES; 308 309 bio = erofs_grab_bio(inode->i_sb, 310 blknr, nblocks, read_endio, false); 311 312 if (IS_ERR(bio)) { 313 err = PTR_ERR(bio); 314 bio = NULL; 315 goto err_out; 316 } 317 } 318 319 err = bio_add_page(bio, page, PAGE_SIZE, 0); 320 /* out of the extent or bio is full */ 321 if (err < PAGE_SIZE) 322 goto submit_bio_retry; 323 324 *last_block = current_block; 325 326 /* shift in advance in case of it followed by too many gaps */ 327 if (unlikely(bio->bi_vcnt >= bio->bi_max_vecs)) { 328 /* err should reassign to 0 after submitting */ 329 err = 0; 330 goto submit_bio_out; 331 } 332 333 return bio; 334 335err_out: 336 /* for sync reading, set page error immediately */ 337 if (!ra) { 338 SetPageError(page); 339 ClearPageUptodate(page); 340 } 341has_updated: 342 unlock_page(page); 343 344 /* if updated manually, continuous pages has a gap */ 345 if (bio != NULL) 346submit_bio_out: 347 __submit_bio(bio, REQ_OP_READ, 0); 348 349 return unlikely(err) ? ERR_PTR(err) : NULL; 350} 351 352/* 353 * since we dont have write or truncate flows, so no inode 354 * locking needs to be held at the moment. 355 */ 356static int erofs_raw_access_readpage(struct file *file, struct page *page) 357{ 358 erofs_off_t last_block; 359 struct bio *bio; 360 361 trace_erofs_readpage(page, true); 362 363 bio = erofs_read_raw_page(NULL, page->mapping, 364 page, &last_block, 1, false); 365 366 if (IS_ERR(bio)) 367 return PTR_ERR(bio); 368 369 DBG_BUGON(bio); /* since we have only one bio -- must be NULL */ 370 return 0; 371} 372 373static int erofs_raw_access_readpages(struct file *filp, 374 struct address_space *mapping, 375 struct list_head *pages, unsigned int nr_pages) 376{ 377 erofs_off_t last_block; 378 struct bio *bio = NULL; 379 gfp_t gfp = readahead_gfp_mask(mapping); 380 struct page *page = list_last_entry(pages, struct page, lru); 381 382 trace_erofs_readpages(mapping->host, page, nr_pages, true); 383 384 for (; nr_pages; --nr_pages) { 385 page = list_entry(pages->prev, struct page, lru); 386 387 prefetchw(&page->flags); 388 list_del(&page->lru); 389 390 if (!add_to_page_cache_lru(page, mapping, page->index, gfp)) { 391 bio = erofs_read_raw_page(bio, mapping, page, 392 &last_block, nr_pages, true); 393 394 /* all the page errors are ignored when readahead */ 395 if (IS_ERR(bio)) { 396 pr_err("%s, readahead error at page %lu of nid %llu\n", 397 __func__, page->index, 398 EROFS_V(mapping->host)->nid); 399 400 bio = NULL; 401 } 402 } 403 404 /* pages could still be locked */ 405 put_page(page); 406 } 407 DBG_BUGON(!list_empty(pages)); 408 409 /* the rare case (end in gaps) */ 410 if (unlikely(bio != NULL)) 411 __submit_bio(bio, REQ_OP_READ, 0); 412 return 0; 413} 414 415/* for uncompressed (aligned) files and raw access for other files */ 416const struct address_space_operations erofs_raw_access_aops = { 417 .readpage = erofs_raw_access_readpage, 418 .readpages = erofs_raw_access_readpages, 419}; 420