diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 76 |
1 files changed, 52 insertions, 24 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e7872e485f13..dafdfa059bf6 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1036,11 +1036,13 @@ out: | |||
1036 | * on error we return an unlocked page and the error value | 1036 | * on error we return an unlocked page and the error value |
1037 | * on success we return a locked page and 0 | 1037 | * on success we return a locked page and 0 |
1038 | */ | 1038 | */ |
1039 | static int prepare_uptodate_page(struct page *page, u64 pos) | 1039 | static int prepare_uptodate_page(struct page *page, u64 pos, |
1040 | bool force_uptodate) | ||
1040 | { | 1041 | { |
1041 | int ret = 0; | 1042 | int ret = 0; |
1042 | 1043 | ||
1043 | if ((pos & (PAGE_CACHE_SIZE - 1)) && !PageUptodate(page)) { | 1044 | if (((pos & (PAGE_CACHE_SIZE - 1)) || force_uptodate) && |
1045 | !PageUptodate(page)) { | ||
1044 | ret = btrfs_readpage(NULL, page); | 1046 | ret = btrfs_readpage(NULL, page); |
1045 | if (ret) | 1047 | if (ret) |
1046 | return ret; | 1048 | return ret; |
@@ -1061,12 +1063,13 @@ static int prepare_uptodate_page(struct page *page, u64 pos) | |||
1061 | static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | 1063 | static noinline int prepare_pages(struct btrfs_root *root, struct file *file, |
1062 | struct page **pages, size_t num_pages, | 1064 | struct page **pages, size_t num_pages, |
1063 | loff_t pos, unsigned long first_index, | 1065 | loff_t pos, unsigned long first_index, |
1064 | size_t write_bytes) | 1066 | size_t write_bytes, bool force_uptodate) |
1065 | { | 1067 | { |
1066 | struct extent_state *cached_state = NULL; | 1068 | struct extent_state *cached_state = NULL; |
1067 | int i; | 1069 | int i; |
1068 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 1070 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
1069 | struct inode *inode = fdentry(file)->d_inode; | 1071 | struct inode *inode = fdentry(file)->d_inode; |
1072 | gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); | ||
1070 | int err = 0; | 1073 | int err = 0; |
1071 | int faili = 0; | 1074 | int faili = 0; |
1072 | u64 start_pos; | 1075 | u64 start_pos; |
@@ -1075,16 +1078,10 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | |||
1075 | start_pos = pos & ~((u64)root->sectorsize - 1); | 1078 | start_pos = pos & ~((u64)root->sectorsize - 1); |
1076 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; | 1079 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; |
1077 | 1080 | ||
1078 | if (start_pos > inode->i_size) { | ||
1079 | err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); | ||
1080 | if (err) | ||
1081 | return err; | ||
1082 | } | ||
1083 | |||
1084 | again: | 1081 | again: |
1085 | for (i = 0; i < num_pages; i++) { | 1082 | for (i = 0; i < num_pages; i++) { |
1086 | pages[i] = find_or_create_page(inode->i_mapping, index + i, | 1083 | pages[i] = find_or_create_page(inode->i_mapping, index + i, |
1087 | GFP_NOFS); | 1084 | mask); |
1088 | if (!pages[i]) { | 1085 | if (!pages[i]) { |
1089 | faili = i - 1; | 1086 | faili = i - 1; |
1090 | err = -ENOMEM; | 1087 | err = -ENOMEM; |
@@ -1092,10 +1089,11 @@ again: | |||
1092 | } | 1089 | } |
1093 | 1090 | ||
1094 | if (i == 0) | 1091 | if (i == 0) |
1095 | err = prepare_uptodate_page(pages[i], pos); | 1092 | err = prepare_uptodate_page(pages[i], pos, |
1093 | force_uptodate); | ||
1096 | if (i == num_pages - 1) | 1094 | if (i == num_pages - 1) |
1097 | err = prepare_uptodate_page(pages[i], | 1095 | err = prepare_uptodate_page(pages[i], |
1098 | pos + write_bytes); | 1096 | pos + write_bytes, false); |
1099 | if (err) { | 1097 | if (err) { |
1100 | page_cache_release(pages[i]); | 1098 | page_cache_release(pages[i]); |
1101 | faili = i - 1; | 1099 | faili = i - 1; |
@@ -1164,6 +1162,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1164 | size_t num_written = 0; | 1162 | size_t num_written = 0; |
1165 | int nrptrs; | 1163 | int nrptrs; |
1166 | int ret = 0; | 1164 | int ret = 0; |
1165 | bool force_page_uptodate = false; | ||
1167 | 1166 | ||
1168 | nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / | 1167 | nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / |
1169 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / | 1168 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / |
@@ -1206,7 +1205,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1206 | * contents of pages from loop to loop | 1205 | * contents of pages from loop to loop |
1207 | */ | 1206 | */ |
1208 | ret = prepare_pages(root, file, pages, num_pages, | 1207 | ret = prepare_pages(root, file, pages, num_pages, |
1209 | pos, first_index, write_bytes); | 1208 | pos, first_index, write_bytes, |
1209 | force_page_uptodate); | ||
1210 | if (ret) { | 1210 | if (ret) { |
1211 | btrfs_delalloc_release_space(inode, | 1211 | btrfs_delalloc_release_space(inode, |
1212 | num_pages << PAGE_CACHE_SHIFT); | 1212 | num_pages << PAGE_CACHE_SHIFT); |
@@ -1223,12 +1223,15 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1223 | if (copied < write_bytes) | 1223 | if (copied < write_bytes) |
1224 | nrptrs = 1; | 1224 | nrptrs = 1; |
1225 | 1225 | ||
1226 | if (copied == 0) | 1226 | if (copied == 0) { |
1227 | force_page_uptodate = true; | ||
1227 | dirty_pages = 0; | 1228 | dirty_pages = 0; |
1228 | else | 1229 | } else { |
1230 | force_page_uptodate = false; | ||
1229 | dirty_pages = (copied + offset + | 1231 | dirty_pages = (copied + offset + |
1230 | PAGE_CACHE_SIZE - 1) >> | 1232 | PAGE_CACHE_SIZE - 1) >> |
1231 | PAGE_CACHE_SHIFT; | 1233 | PAGE_CACHE_SHIFT; |
1234 | } | ||
1232 | 1235 | ||
1233 | /* | 1236 | /* |
1234 | * If we had a short copy we need to release the excess delaloc | 1237 | * If we had a short copy we need to release the excess delaloc |
@@ -1338,6 +1341,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1338 | struct inode *inode = fdentry(file)->d_inode; | 1341 | struct inode *inode = fdentry(file)->d_inode; |
1339 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1342 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1340 | loff_t *ppos = &iocb->ki_pos; | 1343 | loff_t *ppos = &iocb->ki_pos; |
1344 | u64 start_pos; | ||
1341 | ssize_t num_written = 0; | 1345 | ssize_t num_written = 0; |
1342 | ssize_t err = 0; | 1346 | ssize_t err = 0; |
1343 | size_t count, ocount; | 1347 | size_t count, ocount; |
@@ -1386,6 +1390,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1386 | file_update_time(file); | 1390 | file_update_time(file); |
1387 | BTRFS_I(inode)->sequence++; | 1391 | BTRFS_I(inode)->sequence++; |
1388 | 1392 | ||
1393 | start_pos = round_down(pos, root->sectorsize); | ||
1394 | if (start_pos > i_size_read(inode)) { | ||
1395 | err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); | ||
1396 | if (err) { | ||
1397 | mutex_unlock(&inode->i_mutex); | ||
1398 | goto out; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1389 | if (unlikely(file->f_flags & O_DIRECT)) { | 1402 | if (unlikely(file->f_flags & O_DIRECT)) { |
1390 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, | 1403 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, |
1391 | pos, ppos, count, ocount); | 1404 | pos, ppos, count, ocount); |
@@ -1603,10 +1616,6 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1603 | goto out; | 1616 | goto out; |
1604 | } | 1617 | } |
1605 | 1618 | ||
1606 | ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start); | ||
1607 | if (ret) | ||
1608 | goto out; | ||
1609 | |||
1610 | locked_end = alloc_end - 1; | 1619 | locked_end = alloc_end - 1; |
1611 | while (1) { | 1620 | while (1) { |
1612 | struct btrfs_ordered_extent *ordered; | 1621 | struct btrfs_ordered_extent *ordered; |
@@ -1652,11 +1661,27 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1652 | if (em->block_start == EXTENT_MAP_HOLE || | 1661 | if (em->block_start == EXTENT_MAP_HOLE || |
1653 | (cur_offset >= inode->i_size && | 1662 | (cur_offset >= inode->i_size && |
1654 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 1663 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
1664 | |||
1665 | /* | ||
1666 | * Make sure we have enough space before we do the | ||
1667 | * allocation. | ||
1668 | */ | ||
1669 | ret = btrfs_check_data_free_space(inode, last_byte - | ||
1670 | cur_offset); | ||
1671 | if (ret) { | ||
1672 | free_extent_map(em); | ||
1673 | break; | ||
1674 | } | ||
1675 | |||
1655 | ret = btrfs_prealloc_file_range(inode, mode, cur_offset, | 1676 | ret = btrfs_prealloc_file_range(inode, mode, cur_offset, |
1656 | last_byte - cur_offset, | 1677 | last_byte - cur_offset, |
1657 | 1 << inode->i_blkbits, | 1678 | 1 << inode->i_blkbits, |
1658 | offset + len, | 1679 | offset + len, |
1659 | &alloc_hint); | 1680 | &alloc_hint); |
1681 | |||
1682 | /* Let go of our reservation. */ | ||
1683 | btrfs_free_reserved_data_space(inode, last_byte - | ||
1684 | cur_offset); | ||
1660 | if (ret < 0) { | 1685 | if (ret < 0) { |
1661 | free_extent_map(em); | 1686 | free_extent_map(em); |
1662 | break; | 1687 | break; |
@@ -1682,8 +1707,6 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1682 | } | 1707 | } |
1683 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, | 1708 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, |
1684 | &cached_state, GFP_NOFS); | 1709 | &cached_state, GFP_NOFS); |
1685 | |||
1686 | btrfs_free_reserved_data_space(inode, alloc_end - alloc_start); | ||
1687 | out: | 1710 | out: |
1688 | mutex_unlock(&inode->i_mutex); | 1711 | mutex_unlock(&inode->i_mutex); |
1689 | return ret; | 1712 | return ret; |
@@ -1809,10 +1832,15 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin) | |||
1809 | switch (origin) { | 1832 | switch (origin) { |
1810 | case SEEK_END: | 1833 | case SEEK_END: |
1811 | case SEEK_CUR: | 1834 | case SEEK_CUR: |
1812 | offset = generic_file_llseek_unlocked(file, offset, origin); | 1835 | offset = generic_file_llseek(file, offset, origin); |
1813 | goto out; | 1836 | goto out; |
1814 | case SEEK_DATA: | 1837 | case SEEK_DATA: |
1815 | case SEEK_HOLE: | 1838 | case SEEK_HOLE: |
1839 | if (offset >= i_size_read(inode)) { | ||
1840 | mutex_unlock(&inode->i_mutex); | ||
1841 | return -ENXIO; | ||
1842 | } | ||
1843 | |||
1816 | ret = find_desired_extent(inode, &offset, origin); | 1844 | ret = find_desired_extent(inode, &offset, origin); |
1817 | if (ret) { | 1845 | if (ret) { |
1818 | mutex_unlock(&inode->i_mutex); | 1846 | mutex_unlock(&inode->i_mutex); |
@@ -1821,11 +1849,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin) | |||
1821 | } | 1849 | } |
1822 | 1850 | ||
1823 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { | 1851 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { |
1824 | ret = -EINVAL; | 1852 | offset = -EINVAL; |
1825 | goto out; | 1853 | goto out; |
1826 | } | 1854 | } |
1827 | if (offset > inode->i_sb->s_maxbytes) { | 1855 | if (offset > inode->i_sb->s_maxbytes) { |
1828 | ret = -EINVAL; | 1856 | offset = -EINVAL; |
1829 | goto out; | 1857 | goto out; |
1830 | } | 1858 | } |
1831 | 1859 | ||