aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/shmem.c77
1 files changed, 38 insertions, 39 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 5dfe79048f6d..ce64b6616376 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -205,6 +205,31 @@ static void shmem_free_blocks(struct inode *inode, long pages)
205 } 205 }
206} 206}
207 207
208static int shmem_reserve_inode(struct super_block *sb)
209{
210 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
211 if (sbinfo->max_inodes) {
212 spin_lock(&sbinfo->stat_lock);
213 if (!sbinfo->free_inodes) {
214 spin_unlock(&sbinfo->stat_lock);
215 return -ENOSPC;
216 }
217 sbinfo->free_inodes--;
218 spin_unlock(&sbinfo->stat_lock);
219 }
220 return 0;
221}
222
223static void shmem_free_inode(struct super_block *sb)
224{
225 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
226 if (sbinfo->max_inodes) {
227 spin_lock(&sbinfo->stat_lock);
228 sbinfo->free_inodes++;
229 spin_unlock(&sbinfo->stat_lock);
230 }
231}
232
208/* 233/*
209 * shmem_recalc_inode - recalculate the size of an inode 234 * shmem_recalc_inode - recalculate the size of an inode
210 * 235 *
@@ -762,7 +787,6 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
762 787
763static void shmem_delete_inode(struct inode *inode) 788static void shmem_delete_inode(struct inode *inode)
764{ 789{
765 struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
766 struct shmem_inode_info *info = SHMEM_I(inode); 790 struct shmem_inode_info *info = SHMEM_I(inode);
767 791
768 if (inode->i_op->truncate == shmem_truncate) { 792 if (inode->i_op->truncate == shmem_truncate) {
@@ -777,11 +801,7 @@ static void shmem_delete_inode(struct inode *inode)
777 } 801 }
778 } 802 }
779 BUG_ON(inode->i_blocks); 803 BUG_ON(inode->i_blocks);
780 if (sbinfo->max_inodes) { 804 shmem_free_inode(inode->i_sb);
781 spin_lock(&sbinfo->stat_lock);
782 sbinfo->free_inodes++;
783 spin_unlock(&sbinfo->stat_lock);
784 }
785 clear_inode(inode); 805 clear_inode(inode);
786} 806}
787 807
@@ -1371,15 +1391,8 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1371 struct shmem_inode_info *info; 1391 struct shmem_inode_info *info;
1372 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 1392 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
1373 1393
1374 if (sbinfo->max_inodes) { 1394 if (shmem_reserve_inode(sb))
1375 spin_lock(&sbinfo->stat_lock); 1395 return NULL;
1376 if (!sbinfo->free_inodes) {
1377 spin_unlock(&sbinfo->stat_lock);
1378 return NULL;
1379 }
1380 sbinfo->free_inodes--;
1381 spin_unlock(&sbinfo->stat_lock);
1382 }
1383 1396
1384 inode = new_inode(sb); 1397 inode = new_inode(sb);
1385 if (inode) { 1398 if (inode) {
@@ -1423,11 +1436,8 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
1423 NULL); 1436 NULL);
1424 break; 1437 break;
1425 } 1438 }
1426 } else if (sbinfo->max_inodes) { 1439 } else
1427 spin_lock(&sbinfo->stat_lock); 1440 shmem_free_inode(sb);
1428 sbinfo->free_inodes++;
1429 spin_unlock(&sbinfo->stat_lock);
1430 }
1431 return inode; 1441 return inode;
1432} 1442}
1433 1443
@@ -1670,22 +1680,16 @@ static int shmem_create(struct inode *dir, struct dentry *dentry, int mode,
1670static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) 1680static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1671{ 1681{
1672 struct inode *inode = old_dentry->d_inode; 1682 struct inode *inode = old_dentry->d_inode;
1673 struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); 1683 int ret;
1674 1684
1675 /* 1685 /*
1676 * No ordinary (disk based) filesystem counts links as inodes; 1686 * No ordinary (disk based) filesystem counts links as inodes;
1677 * but each new link needs a new dentry, pinning lowmem, and 1687 * but each new link needs a new dentry, pinning lowmem, and
1678 * tmpfs dentries cannot be pruned until they are unlinked. 1688 * tmpfs dentries cannot be pruned until they are unlinked.
1679 */ 1689 */
1680 if (sbinfo->max_inodes) { 1690 ret = shmem_reserve_inode(inode->i_sb);
1681 spin_lock(&sbinfo->stat_lock); 1691 if (ret)
1682 if (!sbinfo->free_inodes) { 1692 goto out;
1683 spin_unlock(&sbinfo->stat_lock);
1684 return -ENOSPC;
1685 }
1686 sbinfo->free_inodes--;
1687 spin_unlock(&sbinfo->stat_lock);
1688 }
1689 1693
1690 dir->i_size += BOGO_DIRENT_SIZE; 1694 dir->i_size += BOGO_DIRENT_SIZE;
1691 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1695 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
@@ -1693,21 +1697,16 @@ static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentr
1693 atomic_inc(&inode->i_count); /* New dentry reference */ 1697 atomic_inc(&inode->i_count); /* New dentry reference */
1694 dget(dentry); /* Extra pinning count for the created dentry */ 1698 dget(dentry); /* Extra pinning count for the created dentry */
1695 d_instantiate(dentry, inode); 1699 d_instantiate(dentry, inode);
1696 return 0; 1700out:
1701 return ret;
1697} 1702}
1698 1703
1699static int shmem_unlink(struct inode *dir, struct dentry *dentry) 1704static int shmem_unlink(struct inode *dir, struct dentry *dentry)
1700{ 1705{
1701 struct inode *inode = dentry->d_inode; 1706 struct inode *inode = dentry->d_inode;
1702 1707
1703 if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode)) { 1708 if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode))
1704 struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); 1709 shmem_free_inode(inode->i_sb);
1705 if (sbinfo->max_inodes) {
1706 spin_lock(&sbinfo->stat_lock);
1707 sbinfo->free_inodes++;
1708 spin_unlock(&sbinfo->stat_lock);
1709 }
1710 }
1711 1710
1712 dir->i_size -= BOGO_DIRENT_SIZE; 1711 dir->i_size -= BOGO_DIRENT_SIZE;
1713 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1712 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;