data.c (ca31fef11dc83e672415d5925a134749761329bd) data.c (a08e67a0280215f74eccf14fda81dd7fed6596ba)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017-2018 HUAWEI, Inc.
4 * https://www.huawei.com/
5 */
6#include "internal.h"
7#include <linux/prefetch.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017-2018 HUAWEI, Inc.
4 * https://www.huawei.com/
5 */
6#include "internal.h"
7#include <linux/prefetch.h>
8#include <linux/iomap.h>
8
9#include <trace/events/erofs.h>
10
11static void erofs_readendio(struct bio *bio)
12{
13 struct bio_vec *bvec;
14 blk_status_t err = bio->bi_status;
15 struct bvec_iter_all iter_all;

--- 287 unchanged lines hidden (view full) ---

303 }
304
305 if (!erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW))
306 return erofs_blknr(map.m_pa);
307
308 return 0;
309}
310
9
10#include <trace/events/erofs.h>
11
12static void erofs_readendio(struct bio *bio)
13{
14 struct bio_vec *bvec;
15 blk_status_t err = bio->bi_status;
16 struct bvec_iter_all iter_all;

--- 287 unchanged lines hidden (view full) ---

304 }
305
306 if (!erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW))
307 return erofs_blknr(map.m_pa);
308
309 return 0;
310}
311
312static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
313 unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
314{
315 int ret;
316 struct erofs_map_blocks map;
317
318 map.m_la = offset;
319 map.m_llen = length;
320
321 ret = erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW);
322 if (ret < 0)
323 return ret;
324
325 iomap->bdev = inode->i_sb->s_bdev;
326 iomap->offset = map.m_la;
327 iomap->length = map.m_llen;
328 iomap->flags = 0;
329
330 if (!(map.m_flags & EROFS_MAP_MAPPED)) {
331 iomap->type = IOMAP_HOLE;
332 iomap->addr = IOMAP_NULL_ADDR;
333 if (!iomap->length)
334 iomap->length = length;
335 return 0;
336 }
337
338 /* that shouldn't happen for now */
339 if (map.m_flags & EROFS_MAP_META) {
340 DBG_BUGON(1);
341 return -ENOTBLK;
342 }
343 iomap->type = IOMAP_MAPPED;
344 iomap->addr = map.m_pa;
345 return 0;
346}
347
348static const struct iomap_ops erofs_iomap_ops = {
349 .iomap_begin = erofs_iomap_begin,
350};
351
352static int erofs_prepare_dio(struct kiocb *iocb, struct iov_iter *to)
353{
354 struct inode *inode = file_inode(iocb->ki_filp);
355 loff_t align = iocb->ki_pos | iov_iter_count(to) |
356 iov_iter_alignment(to);
357 struct block_device *bdev = inode->i_sb->s_bdev;
358 unsigned int blksize_mask;
359
360 if (bdev)
361 blksize_mask = (1 << ilog2(bdev_logical_block_size(bdev))) - 1;
362 else
363 blksize_mask = (1 << inode->i_blkbits) - 1;
364
365 if (align & blksize_mask)
366 return -EINVAL;
367
368 /*
369 * Temporarily fall back tail-packing inline to buffered I/O instead
370 * since tail-packing inline support relies on an iomap core update.
371 */
372 if (EROFS_I(inode)->datalayout == EROFS_INODE_FLAT_INLINE &&
373 iocb->ki_pos + iov_iter_count(to) >
374 rounddown(inode->i_size, EROFS_BLKSIZ))
375 return 1;
376 return 0;
377}
378
379static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
380{
381 /* no need taking (shared) inode lock since it's a ro filesystem */
382 if (!iov_iter_count(to))
383 return 0;
384
385 if (iocb->ki_flags & IOCB_DIRECT) {
386 int err = erofs_prepare_dio(iocb, to);
387
388 if (!err)
389 return iomap_dio_rw(iocb, to, &erofs_iomap_ops,
390 NULL, 0);
391 if (err < 0)
392 return err;
393 }
394 return filemap_read(iocb, to, 0);
395}
396
311/* for uncompressed (aligned) files and raw access for other files */
312const struct address_space_operations erofs_raw_access_aops = {
313 .readpage = erofs_raw_access_readpage,
314 .readahead = erofs_raw_access_readahead,
315 .bmap = erofs_bmap,
397/* for uncompressed (aligned) files and raw access for other files */
398const struct address_space_operations erofs_raw_access_aops = {
399 .readpage = erofs_raw_access_readpage,
400 .readahead = erofs_raw_access_readahead,
401 .bmap = erofs_bmap,
402 .direct_IO = noop_direct_IO,
316};
403};
404
405const struct file_operations erofs_file_fops = {
406 .llseek = generic_file_llseek,
407 .read_iter = erofs_file_read_iter,
408 .mmap = generic_file_readonly_mmap,
409 .splice_read = generic_file_splice_read,
410};