aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-01-12 05:01:12 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-01-12 05:01:12 -0500
commit1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch)
tree44db563f64cf5f8d62af8f99a61e2b248c44ea3a /fs/btrfs/file.c
parent03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff)
parentf9eccf24615672896dc13251410c3f2f33a14f95 (diff)
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano: - Fix the vt8500 timer leading to a system lock up when dealing with too small delta (Roman Volkov) - Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST (Daniel Lezcano) - Prevent to compile timers using the 'iomem' API when the architecture has not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 977e715f0bf2..0f09526aa7d9 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1291,7 +1291,8 @@ out:
1291 * on error we return an unlocked page and the error value 1291 * on error we return an unlocked page and the error value
1292 * on success we return a locked page and 0 1292 * on success we return a locked page and 0
1293 */ 1293 */
1294static int prepare_uptodate_page(struct page *page, u64 pos, 1294static int prepare_uptodate_page(struct inode *inode,
1295 struct page *page, u64 pos,
1295 bool force_uptodate) 1296 bool force_uptodate)
1296{ 1297{
1297 int ret = 0; 1298 int ret = 0;
@@ -1306,6 +1307,10 @@ static int prepare_uptodate_page(struct page *page, u64 pos,
1306 unlock_page(page); 1307 unlock_page(page);
1307 return -EIO; 1308 return -EIO;
1308 } 1309 }
1310 if (page->mapping != inode->i_mapping) {
1311 unlock_page(page);
1312 return -EAGAIN;
1313 }
1309 } 1314 }
1310 return 0; 1315 return 0;
1311} 1316}
@@ -1324,6 +1329,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
1324 int faili; 1329 int faili;
1325 1330
1326 for (i = 0; i < num_pages; i++) { 1331 for (i = 0; i < num_pages; i++) {
1332again:
1327 pages[i] = find_or_create_page(inode->i_mapping, index + i, 1333 pages[i] = find_or_create_page(inode->i_mapping, index + i,
1328 mask | __GFP_WRITE); 1334 mask | __GFP_WRITE);
1329 if (!pages[i]) { 1335 if (!pages[i]) {
@@ -1333,13 +1339,17 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
1333 } 1339 }
1334 1340
1335 if (i == 0) 1341 if (i == 0)
1336 err = prepare_uptodate_page(pages[i], pos, 1342 err = prepare_uptodate_page(inode, pages[i], pos,
1337 force_uptodate); 1343 force_uptodate);
1338 if (i == num_pages - 1) 1344 if (!err && i == num_pages - 1)
1339 err = prepare_uptodate_page(pages[i], 1345 err = prepare_uptodate_page(inode, pages[i],
1340 pos + write_bytes, false); 1346 pos + write_bytes, false);
1341 if (err) { 1347 if (err) {
1342 page_cache_release(pages[i]); 1348 page_cache_release(pages[i]);
1349 if (err == -EAGAIN) {
1350 err = 0;
1351 goto again;
1352 }
1343 faili = i - 1; 1353 faili = i - 1;
1344 goto fail; 1354 goto fail;
1345 } 1355 }
@@ -1882,8 +1892,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
1882 struct btrfs_log_ctx ctx; 1892 struct btrfs_log_ctx ctx;
1883 int ret = 0; 1893 int ret = 0;
1884 bool full_sync = 0; 1894 bool full_sync = 0;
1885 const u64 len = end - start + 1; 1895 u64 len;
1886 1896
1897 /*
1898 * The range length can be represented by u64, we have to do the typecasts
1899 * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
1900 */
1901 len = (u64)end - (u64)start + 1;
1887 trace_btrfs_sync_file(file, datasync); 1902 trace_btrfs_sync_file(file, datasync);
1888 1903
1889 /* 1904 /*
@@ -2071,8 +2086,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
2071 } 2086 }
2072 } 2087 }
2073 if (!full_sync) { 2088 if (!full_sync) {
2074 ret = btrfs_wait_ordered_range(inode, start, 2089 ret = btrfs_wait_ordered_range(inode, start, len);
2075 end - start + 1);
2076 if (ret) { 2090 if (ret) {
2077 btrfs_end_transaction(trans, root); 2091 btrfs_end_transaction(trans, root);
2078 goto out; 2092 goto out;