diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/ext4.h | 11 | ||||
-rw-r--r-- | fs/ext4/extents.c | 9 | ||||
-rw-r--r-- | fs/ext4/inline.c | 233 | ||||
-rw-r--r-- | fs/ext4/inode.c | 103 | ||||
-rw-r--r-- | fs/ext4/xattr.h | 26 |
5 files changed, 340 insertions, 42 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index c827e47d556..9f4efc6c37b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -2018,8 +2018,19 @@ struct buffer_head *ext4_getblk(handle_t *, struct inode *, | |||
2018 | ext4_lblk_t, int, int *); | 2018 | ext4_lblk_t, int, int *); |
2019 | struct buffer_head *ext4_bread(handle_t *, struct inode *, | 2019 | struct buffer_head *ext4_bread(handle_t *, struct inode *, |
2020 | ext4_lblk_t, int, int *); | 2020 | ext4_lblk_t, int, int *); |
2021 | int ext4_get_block_write(struct inode *inode, sector_t iblock, | ||
2022 | struct buffer_head *bh_result, int create); | ||
2021 | int ext4_get_block(struct inode *inode, sector_t iblock, | 2023 | int ext4_get_block(struct inode *inode, sector_t iblock, |
2022 | struct buffer_head *bh_result, int create); | 2024 | struct buffer_head *bh_result, int create); |
2025 | int ext4_walk_page_buffers(handle_t *handle, | ||
2026 | struct buffer_head *head, | ||
2027 | unsigned from, | ||
2028 | unsigned to, | ||
2029 | int *partial, | ||
2030 | int (*fn)(handle_t *handle, | ||
2031 | struct buffer_head *bh)); | ||
2032 | int do_journal_get_write_access(handle_t *handle, | ||
2033 | struct buffer_head *bh); | ||
2023 | 2034 | ||
2024 | extern struct inode *ext4_iget(struct super_block *, unsigned long); | 2035 | extern struct inode *ext4_iget(struct super_block *, unsigned long); |
2025 | extern int ext4_write_inode(struct inode *, struct writeback_control *); | 2036 | extern int ext4_write_inode(struct inode *, struct writeback_control *); |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 1dc19a7b449..f2659f51b23 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/fiemap.h> | 42 | #include <linux/fiemap.h> |
43 | #include "ext4_jbd2.h" | 43 | #include "ext4_jbd2.h" |
44 | #include "ext4_extents.h" | 44 | #include "ext4_extents.h" |
45 | #include "xattr.h" | ||
45 | 46 | ||
46 | #include <trace/events/ext4.h> | 47 | #include <trace/events/ext4.h> |
47 | 48 | ||
@@ -2310,7 +2311,13 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks, | |||
2310 | int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) | 2311 | int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) |
2311 | { | 2312 | { |
2312 | int index; | 2313 | int index; |
2313 | int depth = ext_depth(inode); | 2314 | int depth; |
2315 | |||
2316 | /* If we are converting the inline data, only one is needed here. */ | ||
2317 | if (ext4_has_inline_data(inode)) | ||
2318 | return 1; | ||
2319 | |||
2320 | depth = ext_depth(inode); | ||
2314 | 2321 | ||
2315 | if (chunk) | 2322 | if (chunk) |
2316 | index = depth * 2; | 2323 | index = depth * 2; |
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index e4a41d5d06d..320ff6fe5d8 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "ext4_jbd2.h" | 14 | #include "ext4_jbd2.h" |
15 | #include "ext4.h" | 15 | #include "ext4.h" |
16 | #include "xattr.h" | 16 | #include "xattr.h" |
17 | #include "truncate.h" | ||
17 | 18 | ||
18 | #define EXT4_XATTR_SYSTEM_DATA "data" | 19 | #define EXT4_XATTR_SYSTEM_DATA "data" |
19 | #define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS)) | 20 | #define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS)) |
@@ -515,6 +516,238 @@ int ext4_readpage_inline(struct inode *inode, struct page *page) | |||
515 | return ret >= 0 ? 0 : ret; | 516 | return ret >= 0 ? 0 : ret; |
516 | } | 517 | } |
517 | 518 | ||
519 | static int ext4_convert_inline_data_to_extent(struct address_space *mapping, | ||
520 | struct inode *inode, | ||
521 | unsigned flags) | ||
522 | { | ||
523 | int ret, needed_blocks; | ||
524 | handle_t *handle = NULL; | ||
525 | int retries = 0, sem_held = 0; | ||
526 | struct page *page = NULL; | ||
527 | unsigned from, to; | ||
528 | struct ext4_iloc iloc; | ||
529 | |||
530 | if (!ext4_has_inline_data(inode)) { | ||
531 | /* | ||
532 | * clear the flag so that no new write | ||
533 | * will trap here again. | ||
534 | */ | ||
535 | ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); | ||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | needed_blocks = ext4_writepage_trans_blocks(inode); | ||
540 | |||
541 | ret = ext4_get_inode_loc(inode, &iloc); | ||
542 | if (ret) | ||
543 | return ret; | ||
544 | |||
545 | retry: | ||
546 | handle = ext4_journal_start(inode, needed_blocks); | ||
547 | if (IS_ERR(handle)) { | ||
548 | ret = PTR_ERR(handle); | ||
549 | handle = NULL; | ||
550 | goto out; | ||
551 | } | ||
552 | |||
553 | /* We cannot recurse into the filesystem as the transaction is already | ||
554 | * started */ | ||
555 | flags |= AOP_FLAG_NOFS; | ||
556 | |||
557 | page = grab_cache_page_write_begin(mapping, 0, flags); | ||
558 | if (!page) { | ||
559 | ret = -ENOMEM; | ||
560 | goto out; | ||
561 | } | ||
562 | |||
563 | down_write(&EXT4_I(inode)->xattr_sem); | ||
564 | sem_held = 1; | ||
565 | /* If some one has already done this for us, just exit. */ | ||
566 | if (!ext4_has_inline_data(inode)) { | ||
567 | ret = 0; | ||
568 | goto out; | ||
569 | } | ||
570 | |||
571 | from = 0; | ||
572 | to = ext4_get_inline_size(inode); | ||
573 | if (!PageUptodate(page)) { | ||
574 | ret = ext4_read_inline_page(inode, page); | ||
575 | if (ret < 0) | ||
576 | goto out; | ||
577 | } | ||
578 | |||
579 | ret = ext4_destroy_inline_data_nolock(handle, inode); | ||
580 | if (ret) | ||
581 | goto out; | ||
582 | |||
583 | if (ext4_should_dioread_nolock(inode)) | ||
584 | ret = __block_write_begin(page, from, to, ext4_get_block_write); | ||
585 | else | ||
586 | ret = __block_write_begin(page, from, to, ext4_get_block); | ||
587 | |||
588 | if (!ret && ext4_should_journal_data(inode)) { | ||
589 | ret = ext4_walk_page_buffers(handle, page_buffers(page), | ||
590 | from, to, NULL, | ||
591 | do_journal_get_write_access); | ||
592 | } | ||
593 | |||
594 | if (ret) { | ||
595 | unlock_page(page); | ||
596 | page_cache_release(page); | ||
597 | ext4_orphan_add(handle, inode); | ||
598 | up_write(&EXT4_I(inode)->xattr_sem); | ||
599 | sem_held = 0; | ||
600 | ext4_journal_stop(handle); | ||
601 | handle = NULL; | ||
602 | ext4_truncate_failed_write(inode); | ||
603 | /* | ||
604 | * If truncate failed early the inode might | ||
605 | * still be on the orphan list; we need to | ||
606 | * make sure the inode is removed from the | ||
607 | * orphan list in that case. | ||
608 | */ | ||
609 | if (inode->i_nlink) | ||
610 | ext4_orphan_del(NULL, inode); | ||
611 | } | ||
612 | |||
613 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | ||
614 | goto retry; | ||
615 | |||
616 | block_commit_write(page, from, to); | ||
617 | out: | ||
618 | if (page) { | ||
619 | unlock_page(page); | ||
620 | page_cache_release(page); | ||
621 | } | ||
622 | if (sem_held) | ||
623 | up_write(&EXT4_I(inode)->xattr_sem); | ||
624 | if (handle) | ||
625 | ext4_journal_stop(handle); | ||
626 | brelse(iloc.bh); | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | /* | ||
631 | * Try to write data in the inode. | ||
632 | * If the inode has inline data, check whether the new write can be | ||
633 | * in the inode also. If not, create the page the handle, move the data | ||
634 | * to the page make it update and let the later codes create extent for it. | ||
635 | */ | ||
636 | int ext4_try_to_write_inline_data(struct address_space *mapping, | ||
637 | struct inode *inode, | ||
638 | loff_t pos, unsigned len, | ||
639 | unsigned flags, | ||
640 | struct page **pagep) | ||
641 | { | ||
642 | int ret; | ||
643 | handle_t *handle; | ||
644 | struct page *page; | ||
645 | struct ext4_iloc iloc; | ||
646 | |||
647 | if (pos + len > ext4_get_max_inline_size(inode)) | ||
648 | goto convert; | ||
649 | |||
650 | ret = ext4_get_inode_loc(inode, &iloc); | ||
651 | if (ret) | ||
652 | return ret; | ||
653 | |||
654 | /* | ||
655 | * The possible write could happen in the inode, | ||
656 | * so try to reserve the space in inode first. | ||
657 | */ | ||
658 | handle = ext4_journal_start(inode, 1); | ||
659 | if (IS_ERR(handle)) { | ||
660 | ret = PTR_ERR(handle); | ||
661 | handle = NULL; | ||
662 | goto out; | ||
663 | } | ||
664 | |||
665 | ret = ext4_prepare_inline_data(handle, inode, pos + len); | ||
666 | if (ret && ret != -ENOSPC) | ||
667 | goto out; | ||
668 | |||
669 | /* We don't have space in inline inode, so convert it to extent. */ | ||
670 | if (ret == -ENOSPC) { | ||
671 | ext4_journal_stop(handle); | ||
672 | brelse(iloc.bh); | ||
673 | goto convert; | ||
674 | } | ||
675 | |||
676 | flags |= AOP_FLAG_NOFS; | ||
677 | |||
678 | page = grab_cache_page_write_begin(mapping, 0, flags); | ||
679 | if (!page) { | ||
680 | ret = -ENOMEM; | ||
681 | goto out; | ||
682 | } | ||
683 | |||
684 | *pagep = page; | ||
685 | down_read(&EXT4_I(inode)->xattr_sem); | ||
686 | if (!ext4_has_inline_data(inode)) { | ||
687 | ret = 0; | ||
688 | unlock_page(page); | ||
689 | page_cache_release(page); | ||
690 | goto out_up_read; | ||
691 | } | ||
692 | |||
693 | if (!PageUptodate(page)) { | ||
694 | ret = ext4_read_inline_page(inode, page); | ||
695 | if (ret < 0) | ||
696 | goto out_up_read; | ||
697 | } | ||
698 | |||
699 | ret = 1; | ||
700 | handle = NULL; | ||
701 | out_up_read: | ||
702 | up_read(&EXT4_I(inode)->xattr_sem); | ||
703 | out: | ||
704 | if (handle) | ||
705 | ext4_journal_stop(handle); | ||
706 | brelse(iloc.bh); | ||
707 | return ret; | ||
708 | convert: | ||
709 | return ext4_convert_inline_data_to_extent(mapping, | ||
710 | inode, flags); | ||
711 | } | ||
712 | |||
713 | int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, | ||
714 | unsigned copied, struct page *page) | ||
715 | { | ||
716 | int ret; | ||
717 | void *kaddr; | ||
718 | struct ext4_iloc iloc; | ||
719 | |||
720 | if (unlikely(copied < len)) { | ||
721 | if (!PageUptodate(page)) { | ||
722 | copied = 0; | ||
723 | goto out; | ||
724 | } | ||
725 | } | ||
726 | |||
727 | ret = ext4_get_inode_loc(inode, &iloc); | ||
728 | if (ret) { | ||
729 | ext4_std_error(inode->i_sb, ret); | ||
730 | copied = 0; | ||
731 | goto out; | ||
732 | } | ||
733 | |||
734 | down_write(&EXT4_I(inode)->xattr_sem); | ||
735 | BUG_ON(!ext4_has_inline_data(inode)); | ||
736 | |||
737 | kaddr = kmap_atomic(page); | ||
738 | ext4_write_inline_data(inode, &iloc, kaddr, pos, len); | ||
739 | kunmap_atomic(kaddr); | ||
740 | SetPageUptodate(page); | ||
741 | /* clear page dirty so that writepages wouldn't work for us. */ | ||
742 | ClearPageDirty(page); | ||
743 | |||
744 | up_write(&EXT4_I(inode)->xattr_sem); | ||
745 | brelse(iloc.bh); | ||
746 | out: | ||
747 | return copied; | ||
748 | } | ||
749 | |||
750 | |||
518 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) | 751 | int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) |
519 | { | 752 | { |
520 | int ret; | 753 | int ret; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1668abf8054..70c8d5f323f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -770,13 +770,13 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, | |||
770 | return NULL; | 770 | return NULL; |
771 | } | 771 | } |
772 | 772 | ||
773 | static int walk_page_buffers(handle_t *handle, | 773 | int ext4_walk_page_buffers(handle_t *handle, |
774 | struct buffer_head *head, | 774 | struct buffer_head *head, |
775 | unsigned from, | 775 | unsigned from, |
776 | unsigned to, | 776 | unsigned to, |
777 | int *partial, | 777 | int *partial, |
778 | int (*fn)(handle_t *handle, | 778 | int (*fn)(handle_t *handle, |
779 | struct buffer_head *bh)) | 779 | struct buffer_head *bh)) |
780 | { | 780 | { |
781 | struct buffer_head *bh; | 781 | struct buffer_head *bh; |
782 | unsigned block_start, block_end; | 782 | unsigned block_start, block_end; |
@@ -826,8 +826,8 @@ static int walk_page_buffers(handle_t *handle, | |||
826 | * is elevated. We'll still have enough credits for the tiny quotafile | 826 | * is elevated. We'll still have enough credits for the tiny quotafile |
827 | * write. | 827 | * write. |
828 | */ | 828 | */ |
829 | static int do_journal_get_write_access(handle_t *handle, | 829 | int do_journal_get_write_access(handle_t *handle, |
830 | struct buffer_head *bh) | 830 | struct buffer_head *bh) |
831 | { | 831 | { |
832 | int dirty = buffer_dirty(bh); | 832 | int dirty = buffer_dirty(bh); |
833 | int ret; | 833 | int ret; |
@@ -850,8 +850,6 @@ static int do_journal_get_write_access(handle_t *handle, | |||
850 | return ret; | 850 | return ret; |
851 | } | 851 | } |
852 | 852 | ||
853 | static int ext4_get_block_write(struct inode *inode, sector_t iblock, | ||
854 | struct buffer_head *bh_result, int create); | ||
855 | static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock, | 853 | static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock, |
856 | struct buffer_head *bh_result, int create); | 854 | struct buffer_head *bh_result, int create); |
857 | static int ext4_write_begin(struct file *file, struct address_space *mapping, | 855 | static int ext4_write_begin(struct file *file, struct address_space *mapping, |
@@ -876,6 +874,17 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, | |||
876 | from = pos & (PAGE_CACHE_SIZE - 1); | 874 | from = pos & (PAGE_CACHE_SIZE - 1); |
877 | to = from + len; | 875 | to = from + len; |
878 | 876 | ||
877 | if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { | ||
878 | ret = ext4_try_to_write_inline_data(mapping, inode, pos, len, | ||
879 | flags, pagep); | ||
880 | if (ret < 0) | ||
881 | goto out; | ||
882 | if (ret == 1) { | ||
883 | ret = 0; | ||
884 | goto out; | ||
885 | } | ||
886 | } | ||
887 | |||
879 | retry: | 888 | retry: |
880 | handle = ext4_journal_start(inode, needed_blocks); | 889 | handle = ext4_journal_start(inode, needed_blocks); |
881 | if (IS_ERR(handle)) { | 890 | if (IS_ERR(handle)) { |
@@ -893,6 +902,7 @@ retry: | |||
893 | ret = -ENOMEM; | 902 | ret = -ENOMEM; |
894 | goto out; | 903 | goto out; |
895 | } | 904 | } |
905 | |||
896 | *pagep = page; | 906 | *pagep = page; |
897 | 907 | ||
898 | if (ext4_should_dioread_nolock(inode)) | 908 | if (ext4_should_dioread_nolock(inode)) |
@@ -901,8 +911,9 @@ retry: | |||
901 | ret = __block_write_begin(page, pos, len, ext4_get_block); | 911 | ret = __block_write_begin(page, pos, len, ext4_get_block); |
902 | 912 | ||
903 | if (!ret && ext4_should_journal_data(inode)) { | 913 | if (!ret && ext4_should_journal_data(inode)) { |
904 | ret = walk_page_buffers(handle, page_buffers(page), | 914 | ret = ext4_walk_page_buffers(handle, page_buffers(page), |
905 | from, to, NULL, do_journal_get_write_access); | 915 | from, to, NULL, |
916 | do_journal_get_write_access); | ||
906 | } | 917 | } |
907 | 918 | ||
908 | if (ret) { | 919 | if (ret) { |
@@ -957,7 +968,12 @@ static int ext4_generic_write_end(struct file *file, | |||
957 | struct inode *inode = mapping->host; | 968 | struct inode *inode = mapping->host; |
958 | handle_t *handle = ext4_journal_current_handle(); | 969 | handle_t *handle = ext4_journal_current_handle(); |
959 | 970 | ||
960 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); | 971 | if (ext4_has_inline_data(inode)) |
972 | copied = ext4_write_inline_data_end(inode, pos, len, | ||
973 | copied, page); | ||
974 | else | ||
975 | copied = block_write_end(file, mapping, pos, | ||
976 | len, copied, page, fsdata); | ||
961 | 977 | ||
962 | /* | 978 | /* |
963 | * No need to use i_size_read() here, the i_size | 979 | * No need to use i_size_read() here, the i_size |
@@ -1114,8 +1130,8 @@ static int ext4_journalled_write_end(struct file *file, | |||
1114 | page_zero_new_buffers(page, from+copied, to); | 1130 | page_zero_new_buffers(page, from+copied, to); |
1115 | } | 1131 | } |
1116 | 1132 | ||
1117 | ret = walk_page_buffers(handle, page_buffers(page), from, | 1133 | ret = ext4_walk_page_buffers(handle, page_buffers(page), from, |
1118 | to, &partial, write_end_fn); | 1134 | to, &partial, write_end_fn); |
1119 | if (!partial) | 1135 | if (!partial) |
1120 | SetPageUptodate(page); | 1136 | SetPageUptodate(page); |
1121 | new_i_size = pos + copied; | 1137 | new_i_size = pos + copied; |
@@ -1903,7 +1919,7 @@ static int __ext4_journalled_writepage(struct page *page, | |||
1903 | ClearPageChecked(page); | 1919 | ClearPageChecked(page); |
1904 | page_bufs = page_buffers(page); | 1920 | page_bufs = page_buffers(page); |
1905 | BUG_ON(!page_bufs); | 1921 | BUG_ON(!page_bufs); |
1906 | walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); | 1922 | ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); |
1907 | /* As soon as we unlock the page, it can go away, but we have | 1923 | /* As soon as we unlock the page, it can go away, but we have |
1908 | * references to buffers so we are safe */ | 1924 | * references to buffers so we are safe */ |
1909 | unlock_page(page); | 1925 | unlock_page(page); |
@@ -1916,11 +1932,11 @@ static int __ext4_journalled_writepage(struct page *page, | |||
1916 | 1932 | ||
1917 | BUG_ON(!ext4_handle_valid(handle)); | 1933 | BUG_ON(!ext4_handle_valid(handle)); |
1918 | 1934 | ||
1919 | ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, | 1935 | ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, |
1920 | do_journal_get_write_access); | 1936 | do_journal_get_write_access); |
1921 | 1937 | ||
1922 | err = walk_page_buffers(handle, page_bufs, 0, len, NULL, | 1938 | err = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, |
1923 | write_end_fn); | 1939 | write_end_fn); |
1924 | if (ret == 0) | 1940 | if (ret == 0) |
1925 | ret = err; | 1941 | ret = err; |
1926 | EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; | 1942 | EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; |
@@ -1928,7 +1944,7 @@ static int __ext4_journalled_writepage(struct page *page, | |||
1928 | if (!ret) | 1944 | if (!ret) |
1929 | ret = err; | 1945 | ret = err; |
1930 | 1946 | ||
1931 | walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one); | 1947 | ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one); |
1932 | ext4_set_inode_state(inode, EXT4_STATE_JDATA); | 1948 | ext4_set_inode_state(inode, EXT4_STATE_JDATA); |
1933 | out: | 1949 | out: |
1934 | return ret; | 1950 | return ret; |
@@ -2007,8 +2023,8 @@ static int ext4_writepage(struct page *page, | |||
2007 | commit_write = 1; | 2023 | commit_write = 1; |
2008 | } | 2024 | } |
2009 | page_bufs = page_buffers(page); | 2025 | page_bufs = page_buffers(page); |
2010 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, | 2026 | if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL, |
2011 | ext4_bh_delay_or_unwritten)) { | 2027 | ext4_bh_delay_or_unwritten)) { |
2012 | /* | 2028 | /* |
2013 | * We don't want to do block allocation, so redirty | 2029 | * We don't want to do block allocation, so redirty |
2014 | * the page and return. We may reach here when we do | 2030 | * the page and return. We may reach here when we do |
@@ -2831,7 +2847,7 @@ static int ext4_releasepage(struct page *page, gfp_t wait) | |||
2831 | * We allocate an uinitialized extent if blocks haven't been allocated. | 2847 | * We allocate an uinitialized extent if blocks haven't been allocated. |
2832 | * The extent will be converted to initialized after the IO is complete. | 2848 | * The extent will be converted to initialized after the IO is complete. |
2833 | */ | 2849 | */ |
2834 | static int ext4_get_block_write(struct inode *inode, sector_t iblock, | 2850 | int ext4_get_block_write(struct inode *inode, sector_t iblock, |
2835 | struct buffer_head *bh_result, int create) | 2851 | struct buffer_head *bh_result, int create) |
2836 | { | 2852 | { |
2837 | ext4_debug("ext4_get_block_write: inode %lu, create flag %d\n", | 2853 | ext4_debug("ext4_get_block_write: inode %lu, create flag %d\n", |
@@ -3738,7 +3754,8 @@ static inline void ext4_iget_extra_inode(struct inode *inode, | |||
3738 | if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { | 3754 | if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { |
3739 | ext4_set_inode_state(inode, EXT4_STATE_XATTR); | 3755 | ext4_set_inode_state(inode, EXT4_STATE_XATTR); |
3740 | ext4_find_inline_data_nolock(inode); | 3756 | ext4_find_inline_data_nolock(inode); |
3741 | } | 3757 | } else |
3758 | EXT4_I(inode)->i_inline_off = 0; | ||
3742 | } | 3759 | } |
3743 | 3760 | ||
3744 | struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | 3761 | struct inode *ext4_iget(struct super_block *sb, unsigned long ino) |
@@ -3907,17 +3924,19 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
3907 | ei->i_file_acl); | 3924 | ei->i_file_acl); |
3908 | ret = -EIO; | 3925 | ret = -EIO; |
3909 | goto bad_inode; | 3926 | goto bad_inode; |
3910 | } else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { | 3927 | } else if (!ext4_has_inline_data(inode)) { |
3911 | if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 3928 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { |
3912 | (S_ISLNK(inode->i_mode) && | 3929 | if ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
3913 | !ext4_inode_is_fast_symlink(inode))) | 3930 | (S_ISLNK(inode->i_mode) && |
3914 | /* Validate extent which is part of inode */ | 3931 | !ext4_inode_is_fast_symlink(inode)))) |
3915 | ret = ext4_ext_check_inode(inode); | 3932 | /* Validate extent which is part of inode */ |
3916 | } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 3933 | ret = ext4_ext_check_inode(inode); |
3917 | (S_ISLNK(inode->i_mode) && | 3934 | } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
3918 | !ext4_inode_is_fast_symlink(inode))) { | 3935 | (S_ISLNK(inode->i_mode) && |
3919 | /* Validate block references which are part of inode */ | 3936 | !ext4_inode_is_fast_symlink(inode))) { |
3920 | ret = ext4_ind_check_inode(inode); | 3937 | /* Validate block references which are part of inode */ |
3938 | ret = ext4_ind_check_inode(inode); | ||
3939 | } | ||
3921 | } | 3940 | } |
3922 | if (ret) | 3941 | if (ret) |
3923 | goto bad_inode; | 3942 | goto bad_inode; |
@@ -4104,9 +4123,10 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4104 | cpu_to_le32(new_encode_dev(inode->i_rdev)); | 4123 | cpu_to_le32(new_encode_dev(inode->i_rdev)); |
4105 | raw_inode->i_block[2] = 0; | 4124 | raw_inode->i_block[2] = 0; |
4106 | } | 4125 | } |
4107 | } else | 4126 | } else if (!ext4_has_inline_data(inode)) { |
4108 | for (block = 0; block < EXT4_N_BLOCKS; block++) | 4127 | for (block = 0; block < EXT4_N_BLOCKS; block++) |
4109 | raw_inode->i_block[block] = ei->i_data[block]; | 4128 | raw_inode->i_block[block] = ei->i_data[block]; |
4129 | } | ||
4110 | 4130 | ||
4111 | raw_inode->i_disk_version = cpu_to_le32(inode->i_version); | 4131 | raw_inode->i_disk_version = cpu_to_le32(inode->i_version); |
4112 | if (ei->i_extra_isize) { | 4132 | if (ei->i_extra_isize) { |
@@ -4793,8 +4813,9 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
4793 | * journal_start/journal_stop which can block and take a long time | 4813 | * journal_start/journal_stop which can block and take a long time |
4794 | */ | 4814 | */ |
4795 | if (page_has_buffers(page)) { | 4815 | if (page_has_buffers(page)) { |
4796 | if (!walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, | 4816 | if (!ext4_walk_page_buffers(NULL, page_buffers(page), |
4797 | ext4_bh_unmapped)) { | 4817 | 0, len, NULL, |
4818 | ext4_bh_unmapped)) { | ||
4798 | /* Wait so that we don't change page under IO */ | 4819 | /* Wait so that we don't change page under IO */ |
4799 | wait_on_page_writeback(page); | 4820 | wait_on_page_writeback(page); |
4800 | ret = VM_FAULT_LOCKED; | 4821 | ret = VM_FAULT_LOCKED; |
@@ -4815,7 +4836,7 @@ retry_alloc: | |||
4815 | } | 4836 | } |
4816 | ret = __block_page_mkwrite(vma, vmf, get_block); | 4837 | ret = __block_page_mkwrite(vma, vmf, get_block); |
4817 | if (!ret && ext4_should_journal_data(inode)) { | 4838 | if (!ret && ext4_should_journal_data(inode)) { |
4818 | if (walk_page_buffers(handle, page_buffers(page), 0, | 4839 | if (ext4_walk_page_buffers(handle, page_buffers(page), 0, |
4819 | PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) { | 4840 | PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) { |
4820 | unlock_page(page); | 4841 | unlock_page(page); |
4821 | ret = VM_FAULT_SIGBUS; | 4842 | ret = VM_FAULT_SIGBUS; |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 646c9b9be8e..db567220623 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
@@ -141,6 +141,15 @@ extern int ext4_init_inline_data(handle_t *handle, struct inode *inode, | |||
141 | extern int ext4_destroy_inline_data(handle_t *handle, struct inode *inode); | 141 | extern int ext4_destroy_inline_data(handle_t *handle, struct inode *inode); |
142 | 142 | ||
143 | extern int ext4_readpage_inline(struct inode *inode, struct page *page); | 143 | extern int ext4_readpage_inline(struct inode *inode, struct page *page); |
144 | extern int ext4_try_to_write_inline_data(struct address_space *mapping, | ||
145 | struct inode *inode, | ||
146 | loff_t pos, unsigned len, | ||
147 | unsigned flags, | ||
148 | struct page **pagep); | ||
149 | extern int ext4_write_inline_data_end(struct inode *inode, | ||
150 | loff_t pos, unsigned len, | ||
151 | unsigned copied, | ||
152 | struct page *page); | ||
144 | # else /* CONFIG_EXT4_FS_XATTR */ | 153 | # else /* CONFIG_EXT4_FS_XATTR */ |
145 | 154 | ||
146 | static inline int | 155 | static inline int |
@@ -262,6 +271,23 @@ static inline int ext4_readpage_inline(struct inode *inode, struct page *page) | |||
262 | { | 271 | { |
263 | return 0; | 272 | return 0; |
264 | } | 273 | } |
274 | |||
275 | static inline int ext4_try_to_write_inline_data(struct address_space *mapping, | ||
276 | struct inode *inode, | ||
277 | loff_t pos, unsigned len, | ||
278 | unsigned flags, | ||
279 | struct page **pagep) | ||
280 | { | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static inline int ext4_write_inline_data_end(struct inode *inode, | ||
285 | loff_t pos, unsigned len, | ||
286 | unsigned copied, | ||
287 | struct page *page) | ||
288 | { | ||
289 | return 0; | ||
290 | } | ||
265 | # endif /* CONFIG_EXT4_FS_XATTR */ | 291 | # endif /* CONFIG_EXT4_FS_XATTR */ |
266 | 292 | ||
267 | #ifdef CONFIG_EXT4_FS_SECURITY | 293 | #ifdef CONFIG_EXT4_FS_SECURITY |