From 9136aeb10d79e94ad17fe6599a9b36b16d0924da Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Fri, 8 Aug 2014 09:20:37 +0800 Subject: [PATCH 5/7] shmem: pass inode to shmem_acct_* methods Taken from https://lkml.org/lkml/2014/7/3/406 This will be used by the next patch. Signed-off-by: Vladimir Davydov Signed-off-by: He Zhe Signed-off-by: Bruce Ashfield --- mm/shmem.c | 59 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 1f18c9d0d93e..0d0463497bcc 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -136,16 +136,20 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb) * (unless MAP_NORESERVE and sysctl_overcommit_memory <= 1), * consistent with the pre-accounting of private mappings ... */ -static inline int shmem_acct_size(unsigned long flags, loff_t size) +static inline int shmem_acct_size(struct inode *inode) { - return (flags & VM_NORESERVE) ? - 0 : security_vm_enough_memory_mm(current->mm, VM_ACCT(size)); + struct shmem_inode_info *info = SHMEM_I(inode); + + return (info->flags & VM_NORESERVE) ? + 0 : security_vm_enough_memory_mm(current->mm, VM_ACCT(inode->i_size)); } -static inline void shmem_unacct_size(unsigned long flags, loff_t size) +static inline void shmem_unacct_size(struct inode *inode) { - if (!(flags & VM_NORESERVE)) - vm_unacct_memory(VM_ACCT(size)); + struct shmem_inode_info *info = SHMEM_I(inode); + + if (!(info->flags & VM_NORESERVE)) + vm_unacct_memory(VM_ACCT(inode->i_size)); } /* @@ -154,15 +158,19 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size) * shmem_getpage reports shmem_acct_block failure as -ENOSPC not -ENOMEM, * so that a failure on a sparse tmpfs mapping will give SIGBUS not OOM. */ -static inline int shmem_acct_block(unsigned long flags) +static inline int shmem_acct_block(struct inode *inode) { - return (flags & VM_NORESERVE) ? + struct shmem_inode_info *info = SHMEM_I(inode); + + return (info->flags & VM_NORESERVE) ? security_vm_enough_memory_mm(current->mm, VM_ACCT(PAGE_CACHE_SIZE)) : 0; } -static inline void shmem_unacct_blocks(unsigned long flags, long pages) +static inline void shmem_unacct_blocks(struct inode *inode, long pages) { - if (flags & VM_NORESERVE) + struct shmem_inode_info *info = SHMEM_I(inode); + + if (info->flags & VM_NORESERVE) vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE)); } @@ -231,7 +239,7 @@ static void shmem_recalc_inode(struct inode *inode) percpu_counter_add(&sbinfo->used_blocks, -freed); info->alloced -= freed; inode->i_blocks -= freed * BLOCKS_PER_PAGE; - shmem_unacct_blocks(info->flags, freed); + shmem_unacct_blocks(inode, freed); } } @@ -630,7 +638,7 @@ static void shmem_evict_inode(struct inode *inode) struct shmem_inode_info *info = SHMEM_I(inode); if (inode->i_mapping->a_ops == &shmem_aops) { - shmem_unacct_size(info->flags, inode->i_size); + shmem_unacct_size(inode); inode->i_size = 0; shmem_truncate_range(inode, 0, (loff_t)-1); if (!list_empty(&info->swaplist)) { @@ -1178,7 +1186,7 @@ repeat: swap_free(swap); } else { - if (shmem_acct_block(info->flags)) { + if (shmem_acct_block(inode)) { error = -ENOSPC; goto failed; } @@ -1270,7 +1278,7 @@ decused: if (sbinfo->max_blocks) percpu_counter_add(&sbinfo->used_blocks, -1); unacct: - shmem_unacct_blocks(info->flags, 1); + shmem_unacct_blocks(inode, 1); failed: if (swap.val && error != -EINVAL && !shmem_confirm_swap(mapping, index, swap)) @@ -2896,8 +2904,8 @@ EXPORT_SYMBOL_GPL(shmem_truncate_range); #define shmem_vm_ops generic_file_vm_ops #define shmem_file_operations ramfs_file_operations #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) -#define shmem_acct_size(flags, size) 0 -#define shmem_unacct_size(flags, size) do {} while (0) +#define shmem_acct_size(inode) 0 +#define shmem_unacct_size(inode) do {} while (0) #endif /* CONFIG_SHMEM */ @@ -2922,17 +2930,13 @@ static struct file *__shmem_file_setup(const char *name, loff_t size, if (size < 0 || size > MAX_LFS_FILESIZE) return ERR_PTR(-EINVAL); - if (shmem_acct_size(flags, size)) - return ERR_PTR(-ENOMEM); - - res = ERR_PTR(-ENOMEM); this.name = name; this.len = strlen(name); this.hash = 0; /* will go */ sb = shm_mnt->mnt_sb; path.dentry = d_alloc_pseudo(sb, &this); if (!path.dentry) - goto put_memory; + return ERR_PTR(-ENOMEM); d_set_d_op(path.dentry, &anon_ops); path.mnt = mntget(shm_mnt); @@ -2945,21 +2949,26 @@ static struct file *__shmem_file_setup(const char *name, loff_t size, d_instantiate(path.dentry, inode); inode->i_size = size; clear_nlink(inode); /* It is unlinked */ + + res = ERR_PTR(-ENOMEM); + if (shmem_acct_size(inode)) + goto put_dentry; + res = ERR_PTR(ramfs_nommu_expand_for_mapping(inode, size)); if (IS_ERR(res)) - goto put_dentry; + goto put_memory; res = alloc_file(&path, FMODE_WRITE | FMODE_READ, &shmem_file_operations); if (IS_ERR(res)) - goto put_dentry; + goto put_memory; return res; +put_memory: + shmem_unacct_size(inode); put_dentry: path_put(&path); -put_memory: - shmem_unacct_size(flags, size); return res; } -- 1.8.1.2