tmpfs: truncate prealloc blocks past i_size
[firefly-linux-kernel-4.4.55.git] / mm / shmem.c
index a59087edf7284838efd078f39a115484b4e6467e..4caf8ed24d6586e32ab910f28f945c01cef6373b 100644 (file)
@@ -569,7 +569,7 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
                        i_size_write(inode, newsize);
                        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
                }
-               if (newsize < oldsize) {
+               if (newsize <= oldsize) {
                        loff_t holebegin = round_up(newsize, PAGE_SIZE);
                        unmap_mapping_range(inode->i_mapping, holebegin, 0, 1);
                        shmem_truncate_range(inode, newsize, (loff_t)-1);
@@ -3395,7 +3395,13 @@ int shmem_zero_setup(struct vm_area_struct *vma)
        struct file *file;
        loff_t size = vma->vm_end - vma->vm_start;
 
-       file = shmem_file_setup("dev/zero", size, vma->vm_flags);
+       /*
+        * Cloning a new file under mmap_sem leads to a lock ordering conflict
+        * between XFS directory reading and selinux: since this file is only
+        * accessible to the user through its mapping, use S_PRIVATE flag to
+        * bypass file security, in the same way as shmem_kernel_file_setup().
+        */
+       file = __shmem_file_setup("dev/zero", size, vma->vm_flags, S_PRIVATE);
        if (IS_ERR(file))
                return PTR_ERR(file);