aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c78
1 files changed, 53 insertions, 25 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 33a28bfde158..4ef24a397684 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -555,11 +555,12 @@ repeat:
555 page_cache_get(page); 555 page_cache_get(page);
556 if (TestSetPageLocked(page)) { 556 if (TestSetPageLocked(page)) {
557 read_unlock_irq(&mapping->tree_lock); 557 read_unlock_irq(&mapping->tree_lock);
558 lock_page(page); 558 __lock_page(page);
559 read_lock_irq(&mapping->tree_lock); 559 read_lock_irq(&mapping->tree_lock);
560 560
561 /* Has the page been truncated while we slept? */ 561 /* Has the page been truncated while we slept? */
562 if (page->mapping != mapping || page->index != offset) { 562 if (unlikely(page->mapping != mapping ||
563 page->index != offset)) {
563 unlock_page(page); 564 unlock_page(page);
564 page_cache_release(page); 565 page_cache_release(page);
565 goto repeat; 566 goto repeat;
@@ -831,8 +832,13 @@ readpage:
831 /* Start the actual read. The read will unlock the page. */ 832 /* Start the actual read. The read will unlock the page. */
832 error = mapping->a_ops->readpage(filp, page); 833 error = mapping->a_ops->readpage(filp, page);
833 834
834 if (unlikely(error)) 835 if (unlikely(error)) {
836 if (error == AOP_TRUNCATED_PAGE) {
837 page_cache_release(page);
838 goto find_page;
839 }
835 goto readpage_error; 840 goto readpage_error;
841 }
836 842
837 if (!PageUptodate(page)) { 843 if (!PageUptodate(page)) {
838 lock_page(page); 844 lock_page(page);
@@ -1152,26 +1158,24 @@ static int fastcall page_cache_read(struct file * file, unsigned long offset)
1152{ 1158{
1153 struct address_space *mapping = file->f_mapping; 1159 struct address_space *mapping = file->f_mapping;
1154 struct page *page; 1160 struct page *page;
1155 int error; 1161 int ret;
1156 1162
1157 page = page_cache_alloc_cold(mapping); 1163 do {
1158 if (!page) 1164 page = page_cache_alloc_cold(mapping);
1159 return -ENOMEM; 1165 if (!page)
1166 return -ENOMEM;
1167
1168 ret = add_to_page_cache_lru(page, mapping, offset, GFP_KERNEL);
1169 if (ret == 0)
1170 ret = mapping->a_ops->readpage(file, page);
1171 else if (ret == -EEXIST)
1172 ret = 0; /* losing race to add is OK */
1160 1173
1161 error = add_to_page_cache_lru(page, mapping, offset, GFP_KERNEL);
1162 if (!error) {
1163 error = mapping->a_ops->readpage(file, page);
1164 page_cache_release(page); 1174 page_cache_release(page);
1165 return error;
1166 }
1167 1175
1168 /* 1176 } while (ret == AOP_TRUNCATED_PAGE);
1169 * We arrive here in the unlikely event that someone 1177
1170 * raced with us and added our page to the cache first 1178 return ret;
1171 * or we are out of memory for radix-tree nodes.
1172 */
1173 page_cache_release(page);
1174 return error == -EEXIST ? 0 : error;
1175} 1179}
1176 1180
1177#define MMAP_LOTSAMISS (100) 1181#define MMAP_LOTSAMISS (100)
@@ -1331,10 +1335,14 @@ page_not_uptodate:
1331 goto success; 1335 goto success;
1332 } 1336 }
1333 1337
1334 if (!mapping->a_ops->readpage(file, page)) { 1338 error = mapping->a_ops->readpage(file, page);
1339 if (!error) {
1335 wait_on_page_locked(page); 1340 wait_on_page_locked(page);
1336 if (PageUptodate(page)) 1341 if (PageUptodate(page))
1337 goto success; 1342 goto success;
1343 } else if (error == AOP_TRUNCATED_PAGE) {
1344 page_cache_release(page);
1345 goto retry_find;
1338 } 1346 }
1339 1347
1340 /* 1348 /*
@@ -1358,10 +1366,14 @@ page_not_uptodate:
1358 goto success; 1366 goto success;
1359 } 1367 }
1360 ClearPageError(page); 1368 ClearPageError(page);
1361 if (!mapping->a_ops->readpage(file, page)) { 1369 error = mapping->a_ops->readpage(file, page);
1370 if (!error) {
1362 wait_on_page_locked(page); 1371 wait_on_page_locked(page);
1363 if (PageUptodate(page)) 1372 if (PageUptodate(page))
1364 goto success; 1373 goto success;
1374 } else if (error == AOP_TRUNCATED_PAGE) {
1375 page_cache_release(page);
1376 goto retry_find;
1365 } 1377 }
1366 1378
1367 /* 1379 /*
@@ -1444,10 +1456,14 @@ page_not_uptodate:
1444 goto success; 1456 goto success;
1445 } 1457 }
1446 1458
1447 if (!mapping->a_ops->readpage(file, page)) { 1459 error = mapping->a_ops->readpage(file, page);
1460 if (!error) {
1448 wait_on_page_locked(page); 1461 wait_on_page_locked(page);
1449 if (PageUptodate(page)) 1462 if (PageUptodate(page))
1450 goto success; 1463 goto success;
1464 } else if (error == AOP_TRUNCATED_PAGE) {
1465 page_cache_release(page);
1466 goto retry_find;
1451 } 1467 }
1452 1468
1453 /* 1469 /*
@@ -1470,10 +1486,14 @@ page_not_uptodate:
1470 } 1486 }
1471 1487
1472 ClearPageError(page); 1488 ClearPageError(page);
1473 if (!mapping->a_ops->readpage(file, page)) { 1489 error = mapping->a_ops->readpage(file, page);
1490 if (!error) {
1474 wait_on_page_locked(page); 1491 wait_on_page_locked(page);
1475 if (PageUptodate(page)) 1492 if (PageUptodate(page))
1476 goto success; 1493 goto success;
1494 } else if (error == AOP_TRUNCATED_PAGE) {
1495 page_cache_release(page);
1496 goto retry_find;
1477 } 1497 }
1478 1498
1479 /* 1499 /*
@@ -1934,12 +1954,16 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
1934 status = a_ops->prepare_write(file, page, offset, offset+bytes); 1954 status = a_ops->prepare_write(file, page, offset, offset+bytes);
1935 if (unlikely(status)) { 1955 if (unlikely(status)) {
1936 loff_t isize = i_size_read(inode); 1956 loff_t isize = i_size_read(inode);
1957
1958 if (status != AOP_TRUNCATED_PAGE)
1959 unlock_page(page);
1960 page_cache_release(page);
1961 if (status == AOP_TRUNCATED_PAGE)
1962 continue;
1937 /* 1963 /*
1938 * prepare_write() may have instantiated a few blocks 1964 * prepare_write() may have instantiated a few blocks
1939 * outside i_size. Trim these off again. 1965 * outside i_size. Trim these off again.
1940 */ 1966 */
1941 unlock_page(page);
1942 page_cache_release(page);
1943 if (pos + bytes > isize) 1967 if (pos + bytes > isize)
1944 vmtruncate(inode, isize); 1968 vmtruncate(inode, isize);
1945 break; 1969 break;
@@ -1952,6 +1976,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
1952 cur_iov, iov_base, bytes); 1976 cur_iov, iov_base, bytes);
1953 flush_dcache_page(page); 1977 flush_dcache_page(page);
1954 status = a_ops->commit_write(file, page, offset, offset+bytes); 1978 status = a_ops->commit_write(file, page, offset, offset+bytes);
1979 if (status == AOP_TRUNCATED_PAGE) {
1980 page_cache_release(page);
1981 continue;
1982 }
1955 if (likely(copied > 0)) { 1983 if (likely(copied > 0)) {
1956 if (!status) 1984 if (!status)
1957 status = copied; 1985 status = copied;