Merge tag 'selinux-pr-20220801' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-starfive.git] / mm / secretmem.c
index f544ec6..71fb78f 100644 (file)
@@ -55,22 +55,28 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf)
        gfp_t gfp = vmf->gfp_mask;
        unsigned long addr;
        struct page *page;
+       vm_fault_t ret;
        int err;
 
        if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode))
                return vmf_error(-EINVAL);
 
+       filemap_invalidate_lock_shared(mapping);
+
 retry:
        page = find_lock_page(mapping, offset);
        if (!page) {
                page = alloc_page(gfp | __GFP_ZERO);
-               if (!page)
-                       return VM_FAULT_OOM;
+               if (!page) {
+                       ret = VM_FAULT_OOM;
+                       goto out;
+               }
 
                err = set_direct_map_invalid_noflush(page);
                if (err) {
                        put_page(page);
-                       return vmf_error(err);
+                       ret = vmf_error(err);
+                       goto out;
                }
 
                __SetPageUptodate(page);
@@ -86,7 +92,8 @@ retry:
                        if (err == -EEXIST)
                                goto retry;
 
-                       return vmf_error(err);
+                       ret = vmf_error(err);
+                       goto out;
                }
 
                addr = (unsigned long)page_address(page);
@@ -94,7 +101,11 @@ retry:
        }
 
        vmf->page = page;
-       return VM_FAULT_LOCKED;
+       ret = VM_FAULT_LOCKED;
+
+out:
+       filemap_invalidate_unlock_shared(mapping);
+       return ret;
 }
 
 static const struct vm_operations_struct secretmem_vm_ops = {
@@ -162,12 +173,20 @@ static int secretmem_setattr(struct user_namespace *mnt_userns,
                             struct dentry *dentry, struct iattr *iattr)
 {
        struct inode *inode = d_inode(dentry);
+       struct address_space *mapping = inode->i_mapping;
        unsigned int ia_valid = iattr->ia_valid;
+       int ret;
+
+       filemap_invalidate_lock(mapping);
 
        if ((ia_valid & ATTR_SIZE) && inode->i_size)
-               return -EINVAL;
+               ret = -EINVAL;
+       else
+               ret = simple_setattr(mnt_userns, dentry, iattr);
 
-       return simple_setattr(mnt_userns, dentry, iattr);
+       filemap_invalidate_unlock(mapping);
+
+       return ret;
 }
 
 static const struct inode_operations secretmem_iops = {