aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/shmem.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index fcedf5464eb7..c1db11cf220d 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -241,9 +241,7 @@ static void shmem_free_blocks(struct inode *inode, long pages)
241 struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); 241 struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
242 if (sbinfo->max_blocks) { 242 if (sbinfo->max_blocks) {
243 percpu_counter_add(&sbinfo->used_blocks, -pages); 243 percpu_counter_add(&sbinfo->used_blocks, -pages);
244 spin_lock(&inode->i_lock);
245 inode->i_blocks -= pages*BLOCKS_PER_PAGE; 244 inode->i_blocks -= pages*BLOCKS_PER_PAGE;
246 spin_unlock(&inode->i_lock);
247 } 245 }
248} 246}
249 247
@@ -432,9 +430,7 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long
432 sbinfo->max_blocks - 1) >= 0) 430 sbinfo->max_blocks - 1) >= 0)
433 return ERR_PTR(-ENOSPC); 431 return ERR_PTR(-ENOSPC);
434 percpu_counter_inc(&sbinfo->used_blocks); 432 percpu_counter_inc(&sbinfo->used_blocks);
435 spin_lock(&inode->i_lock);
436 inode->i_blocks += BLOCKS_PER_PAGE; 433 inode->i_blocks += BLOCKS_PER_PAGE;
437 spin_unlock(&inode->i_lock);
438 } 434 }
439 435
440 spin_unlock(&info->lock); 436 spin_unlock(&info->lock);
@@ -1421,9 +1417,7 @@ repeat:
1421 shmem_acct_block(info->flags)) 1417 shmem_acct_block(info->flags))
1422 goto nospace; 1418 goto nospace;
1423 percpu_counter_inc(&sbinfo->used_blocks); 1419 percpu_counter_inc(&sbinfo->used_blocks);
1424 spin_lock(&inode->i_lock);
1425 inode->i_blocks += BLOCKS_PER_PAGE; 1420 inode->i_blocks += BLOCKS_PER_PAGE;
1426 spin_unlock(&inode->i_lock);
1427 } else if (shmem_acct_block(info->flags)) 1421 } else if (shmem_acct_block(info->flags))
1428 goto nospace; 1422 goto nospace;
1429 1423
@@ -1434,8 +1428,10 @@ repeat:
1434 spin_unlock(&info->lock); 1428 spin_unlock(&info->lock);
1435 filepage = shmem_alloc_page(gfp, info, idx); 1429 filepage = shmem_alloc_page(gfp, info, idx);
1436 if (!filepage) { 1430 if (!filepage) {
1431 spin_lock(&info->lock);
1437 shmem_unacct_blocks(info->flags, 1); 1432 shmem_unacct_blocks(info->flags, 1);
1438 shmem_free_blocks(inode, 1); 1433 shmem_free_blocks(inode, 1);
1434 spin_unlock(&info->lock);
1439 error = -ENOMEM; 1435 error = -ENOMEM;
1440 goto failed; 1436 goto failed;
1441 } 1437 }
@@ -1449,8 +1445,10 @@ repeat:
1449 current->mm, GFP_KERNEL); 1445 current->mm, GFP_KERNEL);
1450 if (error) { 1446 if (error) {
1451 page_cache_release(filepage); 1447 page_cache_release(filepage);
1448 spin_lock(&info->lock);
1452 shmem_unacct_blocks(info->flags, 1); 1449 shmem_unacct_blocks(info->flags, 1);
1453 shmem_free_blocks(inode, 1); 1450 shmem_free_blocks(inode, 1);
1451 spin_unlock(&info->lock);
1454 filepage = NULL; 1452 filepage = NULL;
1455 goto failed; 1453 goto failed;
1456 } 1454 }
@@ -1480,10 +1478,10 @@ repeat:
1480 * be done automatically. 1478 * be done automatically.
1481 */ 1479 */
1482 if (ret) { 1480 if (ret) {
1483 spin_unlock(&info->lock);
1484 page_cache_release(filepage);
1485 shmem_unacct_blocks(info->flags, 1); 1481 shmem_unacct_blocks(info->flags, 1);
1486 shmem_free_blocks(inode, 1); 1482 shmem_free_blocks(inode, 1);
1483 spin_unlock(&info->lock);
1484 page_cache_release(filepage);
1487 filepage = NULL; 1485 filepage = NULL;
1488 if (error) 1486 if (error)
1489 goto failed; 1487 goto failed;