diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 59cbdb120ad0..3c3abff731a7 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -74,7 +74,7 @@ struct inode_defrag { | |||
74 | * If an existing record is found the defrag item you | 74 | * If an existing record is found the defrag item you |
75 | * pass in is freed | 75 | * pass in is freed |
76 | */ | 76 | */ |
77 | static int __btrfs_add_inode_defrag(struct inode *inode, | 77 | static void __btrfs_add_inode_defrag(struct inode *inode, |
78 | struct inode_defrag *defrag) | 78 | struct inode_defrag *defrag) |
79 | { | 79 | { |
80 | struct btrfs_root *root = BTRFS_I(inode)->root; | 80 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -106,11 +106,11 @@ static int __btrfs_add_inode_defrag(struct inode *inode, | |||
106 | BTRFS_I(inode)->in_defrag = 1; | 106 | BTRFS_I(inode)->in_defrag = 1; |
107 | rb_link_node(&defrag->rb_node, parent, p); | 107 | rb_link_node(&defrag->rb_node, parent, p); |
108 | rb_insert_color(&defrag->rb_node, &root->fs_info->defrag_inodes); | 108 | rb_insert_color(&defrag->rb_node, &root->fs_info->defrag_inodes); |
109 | return 0; | 109 | return; |
110 | 110 | ||
111 | exists: | 111 | exists: |
112 | kfree(defrag); | 112 | kfree(defrag); |
113 | return 0; | 113 | return; |
114 | 114 | ||
115 | } | 115 | } |
116 | 116 | ||
@@ -123,7 +123,6 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, | |||
123 | { | 123 | { |
124 | struct btrfs_root *root = BTRFS_I(inode)->root; | 124 | struct btrfs_root *root = BTRFS_I(inode)->root; |
125 | struct inode_defrag *defrag; | 125 | struct inode_defrag *defrag; |
126 | int ret = 0; | ||
127 | u64 transid; | 126 | u64 transid; |
128 | 127 | ||
129 | if (!btrfs_test_opt(root, AUTO_DEFRAG)) | 128 | if (!btrfs_test_opt(root, AUTO_DEFRAG)) |
@@ -150,9 +149,11 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, | |||
150 | 149 | ||
151 | spin_lock(&root->fs_info->defrag_inodes_lock); | 150 | spin_lock(&root->fs_info->defrag_inodes_lock); |
152 | if (!BTRFS_I(inode)->in_defrag) | 151 | if (!BTRFS_I(inode)->in_defrag) |
153 | ret = __btrfs_add_inode_defrag(inode, defrag); | 152 | __btrfs_add_inode_defrag(inode, defrag); |
153 | else | ||
154 | kfree(defrag); | ||
154 | spin_unlock(&root->fs_info->defrag_inodes_lock); | 155 | spin_unlock(&root->fs_info->defrag_inodes_lock); |
155 | return ret; | 156 | return 0; |
156 | } | 157 | } |
157 | 158 | ||
158 | /* | 159 | /* |
@@ -855,7 +856,8 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, | |||
855 | btrfs_drop_extent_cache(inode, start, end - 1, 0); | 856 | btrfs_drop_extent_cache(inode, start, end - 1, 0); |
856 | 857 | ||
857 | path = btrfs_alloc_path(); | 858 | path = btrfs_alloc_path(); |
858 | BUG_ON(!path); | 859 | if (!path) |
860 | return -ENOMEM; | ||
859 | again: | 861 | again: |
860 | recow = 0; | 862 | recow = 0; |
861 | split = start; | 863 | split = start; |
@@ -1059,7 +1061,7 @@ static int prepare_uptodate_page(struct page *page, u64 pos) | |||
1059 | static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | 1061 | static noinline int prepare_pages(struct btrfs_root *root, struct file *file, |
1060 | struct page **pages, size_t num_pages, | 1062 | struct page **pages, size_t num_pages, |
1061 | loff_t pos, unsigned long first_index, | 1063 | loff_t pos, unsigned long first_index, |
1062 | unsigned long last_index, size_t write_bytes) | 1064 | size_t write_bytes) |
1063 | { | 1065 | { |
1064 | struct extent_state *cached_state = NULL; | 1066 | struct extent_state *cached_state = NULL; |
1065 | int i; | 1067 | int i; |
@@ -1073,15 +1075,10 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | |||
1073 | start_pos = pos & ~((u64)root->sectorsize - 1); | 1075 | start_pos = pos & ~((u64)root->sectorsize - 1); |
1074 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; | 1076 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; |
1075 | 1077 | ||
1076 | if (start_pos > inode->i_size) { | ||
1077 | err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); | ||
1078 | if (err) | ||
1079 | return err; | ||
1080 | } | ||
1081 | |||
1082 | again: | 1078 | again: |
1083 | for (i = 0; i < num_pages; i++) { | 1079 | for (i = 0; i < num_pages; i++) { |
1084 | pages[i] = grab_cache_page(inode->i_mapping, index + i); | 1080 | pages[i] = find_or_create_page(inode->i_mapping, index + i, |
1081 | GFP_NOFS); | ||
1085 | if (!pages[i]) { | 1082 | if (!pages[i]) { |
1086 | faili = i - 1; | 1083 | faili = i - 1; |
1087 | err = -ENOMEM; | 1084 | err = -ENOMEM; |
@@ -1158,7 +1155,6 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1158 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1155 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1159 | struct page **pages = NULL; | 1156 | struct page **pages = NULL; |
1160 | unsigned long first_index; | 1157 | unsigned long first_index; |
1161 | unsigned long last_index; | ||
1162 | size_t num_written = 0; | 1158 | size_t num_written = 0; |
1163 | int nrptrs; | 1159 | int nrptrs; |
1164 | int ret = 0; | 1160 | int ret = 0; |
@@ -1171,7 +1167,6 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1171 | return -ENOMEM; | 1167 | return -ENOMEM; |
1172 | 1168 | ||
1173 | first_index = pos >> PAGE_CACHE_SHIFT; | 1169 | first_index = pos >> PAGE_CACHE_SHIFT; |
1174 | last_index = (pos + iov_iter_count(i)) >> PAGE_CACHE_SHIFT; | ||
1175 | 1170 | ||
1176 | while (iov_iter_count(i) > 0) { | 1171 | while (iov_iter_count(i) > 0) { |
1177 | size_t offset = pos & (PAGE_CACHE_SIZE - 1); | 1172 | size_t offset = pos & (PAGE_CACHE_SIZE - 1); |
@@ -1205,8 +1200,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1205 | * contents of pages from loop to loop | 1200 | * contents of pages from loop to loop |
1206 | */ | 1201 | */ |
1207 | ret = prepare_pages(root, file, pages, num_pages, | 1202 | ret = prepare_pages(root, file, pages, num_pages, |
1208 | pos, first_index, last_index, | 1203 | pos, first_index, write_bytes); |
1209 | write_bytes); | ||
1210 | if (ret) { | 1204 | if (ret) { |
1211 | btrfs_delalloc_release_space(inode, | 1205 | btrfs_delalloc_release_space(inode, |
1212 | num_pages << PAGE_CACHE_SHIFT); | 1206 | num_pages << PAGE_CACHE_SHIFT); |
@@ -1238,9 +1232,11 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, | |||
1238 | * managed to copy. | 1232 | * managed to copy. |
1239 | */ | 1233 | */ |
1240 | if (num_pages > dirty_pages) { | 1234 | if (num_pages > dirty_pages) { |
1241 | if (copied > 0) | 1235 | if (copied > 0) { |
1242 | atomic_inc( | 1236 | spin_lock(&BTRFS_I(inode)->lock); |
1243 | &BTRFS_I(inode)->outstanding_extents); | 1237 | BTRFS_I(inode)->outstanding_extents++; |
1238 | spin_unlock(&BTRFS_I(inode)->lock); | ||
1239 | } | ||
1244 | btrfs_delalloc_release_space(inode, | 1240 | btrfs_delalloc_release_space(inode, |
1245 | (num_pages - dirty_pages) << | 1241 | (num_pages - dirty_pages) << |
1246 | PAGE_CACHE_SHIFT); | 1242 | PAGE_CACHE_SHIFT); |
@@ -1336,6 +1332,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1336 | struct inode *inode = fdentry(file)->d_inode; | 1332 | struct inode *inode = fdentry(file)->d_inode; |
1337 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1333 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1338 | loff_t *ppos = &iocb->ki_pos; | 1334 | loff_t *ppos = &iocb->ki_pos; |
1335 | u64 start_pos; | ||
1339 | ssize_t num_written = 0; | 1336 | ssize_t num_written = 0; |
1340 | ssize_t err = 0; | 1337 | ssize_t err = 0; |
1341 | size_t count, ocount; | 1338 | size_t count, ocount; |
@@ -1384,6 +1381,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1384 | file_update_time(file); | 1381 | file_update_time(file); |
1385 | BTRFS_I(inode)->sequence++; | 1382 | BTRFS_I(inode)->sequence++; |
1386 | 1383 | ||
1384 | start_pos = round_down(pos, root->sectorsize); | ||
1385 | if (start_pos > i_size_read(inode)) { | ||
1386 | err = btrfs_cont_expand(inode, i_size_read(inode), start_pos); | ||
1387 | if (err) { | ||
1388 | mutex_unlock(&inode->i_mutex); | ||
1389 | goto out; | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1387 | if (unlikely(file->f_flags & O_DIRECT)) { | 1393 | if (unlikely(file->f_flags & O_DIRECT)) { |
1388 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, | 1394 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, |
1389 | pos, ppos, count, ocount); | 1395 | pos, ppos, count, ocount); |
@@ -1638,11 +1644,15 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1638 | 1644 | ||
1639 | cur_offset = alloc_start; | 1645 | cur_offset = alloc_start; |
1640 | while (1) { | 1646 | while (1) { |
1647 | u64 actual_end; | ||
1648 | |||
1641 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, | 1649 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, |
1642 | alloc_end - cur_offset, 0); | 1650 | alloc_end - cur_offset, 0); |
1643 | BUG_ON(IS_ERR_OR_NULL(em)); | 1651 | BUG_ON(IS_ERR_OR_NULL(em)); |
1644 | last_byte = min(extent_map_end(em), alloc_end); | 1652 | last_byte = min(extent_map_end(em), alloc_end); |
1653 | actual_end = min_t(u64, extent_map_end(em), offset + len); | ||
1645 | last_byte = (last_byte + mask) & ~mask; | 1654 | last_byte = (last_byte + mask) & ~mask; |
1655 | |||
1646 | if (em->block_start == EXTENT_MAP_HOLE || | 1656 | if (em->block_start == EXTENT_MAP_HOLE || |
1647 | (cur_offset >= inode->i_size && | 1657 | (cur_offset >= inode->i_size && |
1648 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 1658 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
@@ -1655,6 +1665,16 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1655 | free_extent_map(em); | 1665 | free_extent_map(em); |
1656 | break; | 1666 | break; |
1657 | } | 1667 | } |
1668 | } else if (actual_end > inode->i_size && | ||
1669 | !(mode & FALLOC_FL_KEEP_SIZE)) { | ||
1670 | /* | ||
1671 | * We didn't need to allocate any more space, but we | ||
1672 | * still extended the size of the file so we need to | ||
1673 | * update i_size. | ||
1674 | */ | ||
1675 | inode->i_ctime = CURRENT_TIME; | ||
1676 | i_size_write(inode, actual_end); | ||
1677 | btrfs_ordered_update_i_size(inode, actual_end, NULL); | ||
1658 | } | 1678 | } |
1659 | free_extent_map(em); | 1679 | free_extent_map(em); |
1660 | 1680 | ||
@@ -1804,10 +1824,14 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin) | |||
1804 | } | 1824 | } |
1805 | } | 1825 | } |
1806 | 1826 | ||
1807 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 1827 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { |
1808 | return -EINVAL; | 1828 | ret = -EINVAL; |
1809 | if (offset > inode->i_sb->s_maxbytes) | 1829 | goto out; |
1810 | return -EINVAL; | 1830 | } |
1831 | if (offset > inode->i_sb->s_maxbytes) { | ||
1832 | ret = -EINVAL; | ||
1833 | goto out; | ||
1834 | } | ||
1811 | 1835 | ||
1812 | /* Special lock needed here? */ | 1836 | /* Special lock needed here? */ |
1813 | if (offset != file->f_pos) { | 1837 | if (offset != file->f_pos) { |