|
@@ -149,6 +149,19 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size)
|
|
|
vm_unacct_memory(VM_ACCT(size));
|
|
|
}
|
|
|
|
|
|
+static inline int shmem_reacct_size(unsigned long flags,
|
|
|
+ loff_t oldsize, loff_t newsize)
|
|
|
+{
|
|
|
+ if (!(flags & VM_NORESERVE)) {
|
|
|
+ if (VM_ACCT(newsize) > VM_ACCT(oldsize))
|
|
|
+ return security_vm_enough_memory_mm(current->mm,
|
|
|
+ VM_ACCT(newsize) - VM_ACCT(oldsize));
|
|
|
+ else if (VM_ACCT(newsize) < VM_ACCT(oldsize))
|
|
|
+ vm_unacct_memory(VM_ACCT(oldsize) - VM_ACCT(newsize));
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* ... whereas tmpfs objects are accounted incrementally as
|
|
|
* pages are allocated, in order to allow huge sparse files.
|
|
@@ -549,6 +562,10 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
|
|
|
loff_t newsize = attr->ia_size;
|
|
|
|
|
|
if (newsize != oldsize) {
|
|
|
+ error = shmem_reacct_size(SHMEM_I(inode)->flags,
|
|
|
+ oldsize, newsize);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
i_size_write(inode, newsize);
|
|
|
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
|
|
|
}
|