aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/shmem.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index dc17551d060a..9e755c166cc5 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1407,20 +1407,14 @@ repeat:
1407 if (sbinfo->max_blocks) { 1407 if (sbinfo->max_blocks) {
1408 if (percpu_counter_compare(&sbinfo->used_blocks, 1408 if (percpu_counter_compare(&sbinfo->used_blocks,
1409 sbinfo->max_blocks) >= 0 || 1409 sbinfo->max_blocks) >= 0 ||
1410 shmem_acct_block(info->flags)) { 1410 shmem_acct_block(info->flags))
1411 spin_unlock(&info->lock); 1411 goto nospace;
1412 error = -ENOSPC;
1413 goto failed;
1414 }
1415 percpu_counter_inc(&sbinfo->used_blocks); 1412 percpu_counter_inc(&sbinfo->used_blocks);
1416 spin_lock(&inode->i_lock); 1413 spin_lock(&inode->i_lock);
1417 inode->i_blocks += BLOCKS_PER_PAGE; 1414 inode->i_blocks += BLOCKS_PER_PAGE;
1418 spin_unlock(&inode->i_lock); 1415 spin_unlock(&inode->i_lock);
1419 } else if (shmem_acct_block(info->flags)) { 1416 } else if (shmem_acct_block(info->flags))
1420 spin_unlock(&info->lock); 1417 goto nospace;
1421 error = -ENOSPC;
1422 goto failed;
1423 }
1424 1418
1425 if (!filepage) { 1419 if (!filepage) {
1426 int ret; 1420 int ret;
@@ -1500,6 +1494,24 @@ done:
1500 error = 0; 1494 error = 0;
1501 goto out; 1495 goto out;
1502 1496
1497nospace:
1498 /*
1499 * Perhaps the page was brought in from swap between find_lock_page
1500 * and taking info->lock? We allow for that at add_to_page_cache_lru,
1501 * but must also avoid reporting a spurious ENOSPC while working on a
1502 * full tmpfs. (When filepage has been passed in to shmem_getpage, it
1503 * is already in page cache, which prevents this race from occurring.)
1504 */
1505 if (!filepage) {
1506 struct page *page = find_get_page(mapping, idx);
1507 if (page) {
1508 spin_unlock(&info->lock);
1509 page_cache_release(page);
1510 goto repeat;
1511 }
1512 }
1513 spin_unlock(&info->lock);
1514 error = -ENOSPC;
1503failed: 1515failed:
1504 if (*pagep != filepage) { 1516 if (*pagep != filepage) {
1505 unlock_page(filepage); 1517 unlock_page(filepage);