diff options
author | David S. Miller <davem@davemloft.net> | 2011-09-22 03:23:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-22 03:23:13 -0400 |
commit | 8decf868790b48a727d7e7ca164f2bcd3c1389c0 (patch) | |
tree | b759a5f861f842af7ea76f9011b579d06e9d5508 /fs/btrfs/file.c | |
parent | 3fc72370186be2f9d4d6ef06d99e1caa5d92c564 (diff) | |
parent | d93dc5c4478c1fd5de85a3e8aece9aad7bbae044 (diff) |
Merge branch 'master' of github.com:davem330/net
Conflicts:
MAINTAINERS
drivers/net/Kconfig
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/wl12xx/main.c
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 49 |
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 | |||
1082 | again: | 1078 | again: |
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) { |