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