aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 658d66959abe..a381cd22f518 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -150,6 +150,8 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
150 spin_lock(&root->fs_info->defrag_inodes_lock); 150 spin_lock(&root->fs_info->defrag_inodes_lock);
151 if (!BTRFS_I(inode)->in_defrag) 151 if (!BTRFS_I(inode)->in_defrag)
152 __btrfs_add_inode_defrag(inode, defrag); 152 __btrfs_add_inode_defrag(inode, defrag);
153 else
154 kfree(defrag);
153 spin_unlock(&root->fs_info->defrag_inodes_lock); 155 spin_unlock(&root->fs_info->defrag_inodes_lock);
154 return 0; 156 return 0;
155} 157}
@@ -1073,12 +1075,6 @@ 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
1082again: 1078again:
1083 for (i = 0; i < num_pages; i++) { 1079 for (i = 0; i < num_pages; i++) {
1084 pages[i] = find_or_create_page(inode->i_mapping, index + i, 1080 pages[i] = find_or_create_page(inode->i_mapping, index + i,
@@ -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
@@ -1797,6 +1817,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1797 goto out; 1817 goto out;
1798 case SEEK_DATA: 1818 case SEEK_DATA:
1799 case SEEK_HOLE: 1819 case SEEK_HOLE:
1820 if (offset >= i_size_read(inode)) {
1821 mutex_unlock(&inode->i_mutex);
1822 return -ENXIO;
1823 }
1824
1800 ret = find_desired_extent(inode, &offset, origin); 1825 ret = find_desired_extent(inode, &offset, origin);
1801 if (ret) { 1826 if (ret) {
1802 mutex_unlock(&inode->i_mutex); 1827 mutex_unlock(&inode->i_mutex);
@@ -1804,10 +1829,14 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1804 } 1829 }
1805 } 1830 }
1806 1831
1807 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) 1832 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
1808 return -EINVAL; 1833 offset = -EINVAL;
1809 if (offset > inode->i_sb->s_maxbytes) 1834 goto out;
1810 return -EINVAL; 1835 }
1836 if (offset > inode->i_sb->s_maxbytes) {
1837 offset = -EINVAL;
1838 goto out;
1839 }
1811 1840
1812 /* Special lock needed here? */ 1841 /* Special lock needed here? */
1813 if (offset != file->f_pos) { 1842 if (offset != file->f_pos) {