summaryrefslogtreecommitdiffstats
path: root/fs/ext4/inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r--fs/ext4/inline.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 01274b1e7d40..65f7ffb5437f 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -771,6 +771,183 @@ ext4_journalled_write_inline_data(struct inode *inode,
771 return iloc.bh; 771 return iloc.bh;
772} 772}
773 773
774/*
775 * Try to make the page cache and handle ready for the inline data case.
776 * We can call this function in 2 cases:
777 * 1. The inode is created and the first write exceeds inline size. We can
778 * clear the inode state safely.
779 * 2. The inode has inline data, then we need to read the data, make it
780 * update and dirty so that ext4_da_writepages can handle it. We don't
781 * need to start the journal since the file's metatdata isn't changed now.
782 */
783static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping,
784 struct inode *inode,
785 unsigned flags,
786 void **fsdata)
787{
788 int ret = 0, inline_size;
789 struct page *page;
790
791 page = grab_cache_page_write_begin(mapping, 0, flags);
792 if (!page)
793 return -ENOMEM;
794
795 down_read(&EXT4_I(inode)->xattr_sem);
796 if (!ext4_has_inline_data(inode)) {
797 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
798 goto out;
799 }
800
801 inline_size = ext4_get_inline_size(inode);
802
803 if (!PageUptodate(page)) {
804 ret = ext4_read_inline_page(inode, page);
805 if (ret < 0)
806 goto out;
807 }
808
809 ret = __block_write_begin(page, 0, inline_size,
810 ext4_da_get_block_prep);
811 if (ret) {
812 ext4_truncate_failed_write(inode);
813 goto out;
814 }
815
816 SetPageDirty(page);
817 SetPageUptodate(page);
818 ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
819 *fsdata = (void *)CONVERT_INLINE_DATA;
820
821out:
822 up_read(&EXT4_I(inode)->xattr_sem);
823 if (page) {
824 unlock_page(page);
825 page_cache_release(page);
826 }
827 return ret;
828}
829
830/*
831 * Prepare the write for the inline data.
832 * If the the data can be written into the inode, we just read
833 * the page and make it uptodate, and start the journal.
834 * Otherwise read the page, makes it dirty so that it can be
835 * handle in writepages(the i_disksize update is left to the
836 * normal ext4_da_write_end).
837 */
838int ext4_da_write_inline_data_begin(struct address_space *mapping,
839 struct inode *inode,
840 loff_t pos, unsigned len,
841 unsigned flags,
842 struct page **pagep,
843 void **fsdata)
844{
845 int ret, inline_size;
846 handle_t *handle;
847 struct page *page;
848 struct ext4_iloc iloc;
849
850 ret = ext4_get_inode_loc(inode, &iloc);
851 if (ret)
852 return ret;
853
854 handle = ext4_journal_start(inode, 1);
855 if (IS_ERR(handle)) {
856 ret = PTR_ERR(handle);
857 handle = NULL;
858 goto out;
859 }
860
861 inline_size = ext4_get_max_inline_size(inode);
862
863 ret = -ENOSPC;
864 if (inline_size >= pos + len) {
865 ret = ext4_prepare_inline_data(handle, inode, pos + len);
866 if (ret && ret != -ENOSPC)
867 goto out;
868 }
869
870 if (ret == -ENOSPC) {
871 ret = ext4_da_convert_inline_data_to_extent(mapping,
872 inode,
873 flags,
874 fsdata);
875 goto out;
876 }
877
878 /*
879 * We cannot recurse into the filesystem as the transaction
880 * is already started.
881 */
882 flags |= AOP_FLAG_NOFS;
883
884 page = grab_cache_page_write_begin(mapping, 0, flags);
885 if (!page) {
886 ret = -ENOMEM;
887 goto out;
888 }
889
890 down_read(&EXT4_I(inode)->xattr_sem);
891 if (!ext4_has_inline_data(inode)) {
892 ret = 0;
893 goto out_release_page;
894 }
895
896 if (!PageUptodate(page)) {
897 ret = ext4_read_inline_page(inode, page);
898 if (ret < 0)
899 goto out_release_page;
900 }
901
902 up_read(&EXT4_I(inode)->xattr_sem);
903 *pagep = page;
904 handle = NULL;
905 brelse(iloc.bh);
906 return 1;
907out_release_page:
908 up_read(&EXT4_I(inode)->xattr_sem);
909 unlock_page(page);
910 page_cache_release(page);
911out:
912 if (handle)
913 ext4_journal_stop(handle);
914 brelse(iloc.bh);
915 return ret;
916}
917
918int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
919 unsigned len, unsigned copied,
920 struct page *page)
921{
922 int i_size_changed = 0;
923
924 copied = ext4_write_inline_data_end(inode, pos, len, copied, page);
925
926 /*
927 * No need to use i_size_read() here, the i_size
928 * cannot change under us because we hold i_mutex.
929 *
930 * But it's important to update i_size while still holding page lock:
931 * page writeout could otherwise come in and zero beyond i_size.
932 */
933 if (pos+copied > inode->i_size) {
934 i_size_write(inode, pos+copied);
935 i_size_changed = 1;
936 }
937 unlock_page(page);
938 page_cache_release(page);
939
940 /*
941 * Don't mark the inode dirty under page lock. First, it unnecessarily
942 * makes the holding time of page lock longer. Second, it forces lock
943 * ordering of page lock and transaction start for journaling
944 * filesystems.
945 */
946 if (i_size_changed)
947 mark_inode_dirty(inode);
948
949 return copied;
950}
774 951
775int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) 952int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
776{ 953{