aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-10-20 09:14:25 -0400
committerArnd Bergmann <arnd@arndb.de>2011-10-20 09:14:25 -0400
commitb4cbb8a4e602ea77b0525d06eff89c6a6070dab3 (patch)
treea5dd723679582505ef3905c90f0c2c032d191b94 /fs/btrfs/file.c
parent526b264163068f77c5f2409031f5e25caf3900a9 (diff)
parentc5d7a9230e5e277f262b6806b7f4d6b35de5a3fb (diff)
Merge branch 'imx-features-for-arnd' of git://git.pengutronix.de/git/imx/linux-2.6 into imx/devel
Conflicts: arch/arm/mach-mx5/clock-mx51-mx53.c arch/arm/mach-mx5/devices-imx53.h
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index e7872e485f13..e4e57d59edb7 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 */
1039static int prepare_uptodate_page(struct page *page, u64 pos) 1039static 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,7 +1063,7 @@ static int prepare_uptodate_page(struct page *page, u64 pos)
1061static noinline int prepare_pages(struct btrfs_root *root, struct file *file, 1063static 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;
@@ -1075,12 +1077,6 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
1075 start_pos = pos & ~((u64)root->sectorsize - 1); 1077 start_pos = pos & ~((u64)root->sectorsize - 1);
1076 last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; 1078 last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT;
1077 1079
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
1084again: 1080again:
1085 for (i = 0; i < num_pages; i++) { 1081 for (i = 0; i < num_pages; i++) {
1086 pages[i] = find_or_create_page(inode->i_mapping, index + i, 1082 pages[i] = find_or_create_page(inode->i_mapping, index + i,
@@ -1092,10 +1088,11 @@ again:
1092 } 1088 }
1093 1089
1094 if (i == 0) 1090 if (i == 0)
1095 err = prepare_uptodate_page(pages[i], pos); 1091 err = prepare_uptodate_page(pages[i], pos,
1092 force_uptodate);
1096 if (i == num_pages - 1) 1093 if (i == num_pages - 1)
1097 err = prepare_uptodate_page(pages[i], 1094 err = prepare_uptodate_page(pages[i],
1098 pos + write_bytes); 1095 pos + write_bytes, false);
1099 if (err) { 1096 if (err) {
1100 page_cache_release(pages[i]); 1097 page_cache_release(pages[i]);
1101 faili = i - 1; 1098 faili = i - 1;
@@ -1164,6 +1161,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1164 size_t num_written = 0; 1161 size_t num_written = 0;
1165 int nrptrs; 1162 int nrptrs;
1166 int ret = 0; 1163 int ret = 0;
1164 bool force_page_uptodate = false;
1167 1165
1168 nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / 1166 nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) /
1169 PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / 1167 PAGE_CACHE_SIZE, PAGE_CACHE_SIZE /
@@ -1206,7 +1204,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1206 * contents of pages from loop to loop 1204 * contents of pages from loop to loop
1207 */ 1205 */
1208 ret = prepare_pages(root, file, pages, num_pages, 1206 ret = prepare_pages(root, file, pages, num_pages,
1209 pos, first_index, write_bytes); 1207 pos, first_index, write_bytes,
1208 force_page_uptodate);
1210 if (ret) { 1209 if (ret) {
1211 btrfs_delalloc_release_space(inode, 1210 btrfs_delalloc_release_space(inode,
1212 num_pages << PAGE_CACHE_SHIFT); 1211 num_pages << PAGE_CACHE_SHIFT);
@@ -1223,12 +1222,15 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1223 if (copied < write_bytes) 1222 if (copied < write_bytes)
1224 nrptrs = 1; 1223 nrptrs = 1;
1225 1224
1226 if (copied == 0) 1225 if (copied == 0) {
1226 force_page_uptodate = true;
1227 dirty_pages = 0; 1227 dirty_pages = 0;
1228 else 1228 } else {
1229 force_page_uptodate = false;
1229 dirty_pages = (copied + offset + 1230 dirty_pages = (copied + offset +
1230 PAGE_CACHE_SIZE - 1) >> 1231 PAGE_CACHE_SIZE - 1) >>
1231 PAGE_CACHE_SHIFT; 1232 PAGE_CACHE_SHIFT;
1233 }
1232 1234
1233 /* 1235 /*
1234 * If we had a short copy we need to release the excess delaloc 1236 * If we had a short copy we need to release the excess delaloc
@@ -1338,6 +1340,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1338 struct inode *inode = fdentry(file)->d_inode; 1340 struct inode *inode = fdentry(file)->d_inode;
1339 struct btrfs_root *root = BTRFS_I(inode)->root; 1341 struct btrfs_root *root = BTRFS_I(inode)->root;
1340 loff_t *ppos = &iocb->ki_pos; 1342 loff_t *ppos = &iocb->ki_pos;
1343 u64 start_pos;
1341 ssize_t num_written = 0; 1344 ssize_t num_written = 0;
1342 ssize_t err = 0; 1345 ssize_t err = 0;
1343 size_t count, ocount; 1346 size_t count, ocount;
@@ -1386,6 +1389,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1386 file_update_time(file); 1389 file_update_time(file);
1387 BTRFS_I(inode)->sequence++; 1390 BTRFS_I(inode)->sequence++;
1388 1391
1392 start_pos = round_down(pos, root->sectorsize);
1393 if (start_pos > i_size_read(inode)) {
1394 err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
1395 if (err) {
1396 mutex_unlock(&inode->i_mutex);
1397 goto out;
1398 }
1399 }
1400
1389 if (unlikely(file->f_flags & O_DIRECT)) { 1401 if (unlikely(file->f_flags & O_DIRECT)) {
1390 num_written = __btrfs_direct_write(iocb, iov, nr_segs, 1402 num_written = __btrfs_direct_write(iocb, iov, nr_segs,
1391 pos, ppos, count, ocount); 1403 pos, ppos, count, ocount);
@@ -1813,6 +1825,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1813 goto out; 1825 goto out;
1814 case SEEK_DATA: 1826 case SEEK_DATA:
1815 case SEEK_HOLE: 1827 case SEEK_HOLE:
1828 if (offset >= i_size_read(inode)) {
1829 mutex_unlock(&inode->i_mutex);
1830 return -ENXIO;
1831 }
1832
1816 ret = find_desired_extent(inode, &offset, origin); 1833 ret = find_desired_extent(inode, &offset, origin);
1817 if (ret) { 1834 if (ret) {
1818 mutex_unlock(&inode->i_mutex); 1835 mutex_unlock(&inode->i_mutex);
@@ -1821,11 +1838,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1821 } 1838 }
1822 1839
1823 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { 1840 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
1824 ret = -EINVAL; 1841 offset = -EINVAL;
1825 goto out; 1842 goto out;
1826 } 1843 }
1827 if (offset > inode->i_sb->s_maxbytes) { 1844 if (offset > inode->i_sb->s_maxbytes) {
1828 ret = -EINVAL; 1845 offset = -EINVAL;
1829 goto out; 1846 goto out;
1830 } 1847 }
1831 1848