diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e23f114e2cfe..1668abf80549 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -649,6 +649,9 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock, | |||
649 | int ret = 0, started = 0; | 649 | int ret = 0, started = 0; |
650 | int dio_credits; | 650 | int dio_credits; |
651 | 651 | ||
652 | if (ext4_has_inline_data(inode)) | ||
653 | return -ERANGE; | ||
654 | |||
652 | map.m_lblk = iblock; | 655 | map.m_lblk = iblock; |
653 | map.m_len = bh->b_size >> inode->i_blkbits; | 656 | map.m_len = bh->b_size >> inode->i_blkbits; |
654 | 657 | ||
@@ -2687,6 +2690,12 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) | |||
2687 | journal_t *journal; | 2690 | journal_t *journal; |
2688 | int err; | 2691 | int err; |
2689 | 2692 | ||
2693 | /* | ||
2694 | * We can get here for an inline file via the FIBMAP ioctl | ||
2695 | */ | ||
2696 | if (ext4_has_inline_data(inode)) | ||
2697 | return 0; | ||
2698 | |||
2690 | if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) && | 2699 | if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) && |
2691 | test_opt(inode->i_sb, DELALLOC)) { | 2700 | test_opt(inode->i_sb, DELALLOC)) { |
2692 | /* | 2701 | /* |
@@ -2732,14 +2741,30 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) | |||
2732 | 2741 | ||
2733 | static int ext4_readpage(struct file *file, struct page *page) | 2742 | static int ext4_readpage(struct file *file, struct page *page) |
2734 | { | 2743 | { |
2744 | int ret = -EAGAIN; | ||
2745 | struct inode *inode = page->mapping->host; | ||
2746 | |||
2735 | trace_ext4_readpage(page); | 2747 | trace_ext4_readpage(page); |
2736 | return mpage_readpage(page, ext4_get_block); | 2748 | |
2749 | if (ext4_has_inline_data(inode)) | ||
2750 | ret = ext4_readpage_inline(inode, page); | ||
2751 | |||
2752 | if (ret == -EAGAIN) | ||
2753 | return mpage_readpage(page, ext4_get_block); | ||
2754 | |||
2755 | return ret; | ||
2737 | } | 2756 | } |
2738 | 2757 | ||
2739 | static int | 2758 | static int |
2740 | ext4_readpages(struct file *file, struct address_space *mapping, | 2759 | ext4_readpages(struct file *file, struct address_space *mapping, |
2741 | struct list_head *pages, unsigned nr_pages) | 2760 | struct list_head *pages, unsigned nr_pages) |
2742 | { | 2761 | { |
2762 | struct inode *inode = mapping->host; | ||
2763 | |||
2764 | /* If the file has inline data, no need to do readpages. */ | ||
2765 | if (ext4_has_inline_data(inode)) | ||
2766 | return 0; | ||
2767 | |||
2743 | return mpage_readpages(mapping, pages, nr_pages, ext4_get_block); | 2768 | return mpage_readpages(mapping, pages, nr_pages, ext4_get_block); |
2744 | } | 2769 | } |
2745 | 2770 | ||
@@ -3078,6 +3103,10 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb, | |||
3078 | if (ext4_should_journal_data(inode)) | 3103 | if (ext4_should_journal_data(inode)) |
3079 | return 0; | 3104 | return 0; |
3080 | 3105 | ||
3106 | /* Let buffer I/O handle the inline data case. */ | ||
3107 | if (ext4_has_inline_data(inode)) | ||
3108 | return 0; | ||
3109 | |||
3081 | trace_ext4_direct_IO_enter(inode, offset, iov_length(iov, nr_segs), rw); | 3110 | trace_ext4_direct_IO_enter(inode, offset, iov_length(iov, nr_segs), rw); |
3082 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | 3111 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) |
3083 | ret = ext4_ext_direct_IO(rw, iocb, iov, offset, nr_segs); | 3112 | ret = ext4_ext_direct_IO(rw, iocb, iov, offset, nr_segs); |