mm: userfaultfd: extract file size check out into a helper
This code is already duplicated twice, and UFFDIO_POISON will do the same check a third time. So, it's worth extracting into a helper to save repetitive lines of code. Link: https://lkml.kernel.org/r/20230707215540.2324998-4-axelrasmussen@google.com Signed-off-by: Axel Rasmussen <axelrasmussen@google.com> Reviewed-by: Peter Xu <peterx@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Brian Geffon <bgeffon@google.com> Cc: Christian Brauner <brauner@kernel.org> Cc: David Hildenbrand <david@redhat.com> Cc: Gaosheng Cui <cuigaosheng1@huawei.com> Cc: Huang, Ying <ying.huang@intel.com> Cc: Hugh Dickins <hughd@google.com> Cc: James Houghton <jthoughton@google.com> Cc: Jan Alexander Steffens (heftig) <heftig@archlinux.org> Cc: Jiaqi Yan <jiaqiyan@google.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Kefeng Wang <wangkefeng.wang@huawei.com> Cc: Liam R. Howlett <Liam.Howlett@oracle.com> Cc: Miaohe Lin <linmiaohe@huawei.com> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Mike Rapoport (IBM) <rppt@kernel.org> Cc: Muchun Song <muchun.song@linux.dev> Cc: Nadav Amit <namit@vmware.com> Cc: Naoya Horiguchi <naoya.horiguchi@nec.com> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Shuah Khan <shuah@kernel.org> Cc: Suleiman Souhlal <suleiman@google.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: T.J. Alumbaugh <talumbau@google.com> Cc: Yu Zhao <yuzhao@google.com> Cc: ZhangPeng <zhangpeng362@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
2ef5d7245d
commit
435cdb41a7
|
@ -45,6 +45,22 @@ struct vm_area_struct *find_dst_vma(struct mm_struct *dst_mm,
|
|||
return dst_vma;
|
||||
}
|
||||
|
||||
/* Check if dst_addr is outside of file's size. Must be called with ptl held. */
|
||||
static bool mfill_file_over_size(struct vm_area_struct *dst_vma,
|
||||
unsigned long dst_addr)
|
||||
{
|
||||
struct inode *inode;
|
||||
pgoff_t offset, max_off;
|
||||
|
||||
if (!dst_vma->vm_file)
|
||||
return false;
|
||||
|
||||
inode = dst_vma->vm_file->f_inode;
|
||||
offset = linear_page_index(dst_vma, dst_addr);
|
||||
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
|
||||
return offset >= max_off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install PTEs, to map dst_addr (within dst_vma) to page.
|
||||
*
|
||||
|
@ -64,8 +80,6 @@ int mfill_atomic_install_pte(pmd_t *dst_pmd,
|
|||
bool page_in_cache = page_mapping(page);
|
||||
spinlock_t *ptl;
|
||||
struct folio *folio;
|
||||
struct inode *inode;
|
||||
pgoff_t offset, max_off;
|
||||
|
||||
_dst_pte = mk_pte(page, dst_vma->vm_page_prot);
|
||||
_dst_pte = pte_mkdirty(_dst_pte);
|
||||
|
@ -81,14 +95,9 @@ int mfill_atomic_install_pte(pmd_t *dst_pmd,
|
|||
if (!dst_pte)
|
||||
goto out;
|
||||
|
||||
if (vma_is_shmem(dst_vma)) {
|
||||
/* serialize against truncate with the page table lock */
|
||||
inode = dst_vma->vm_file->f_inode;
|
||||
offset = linear_page_index(dst_vma, dst_addr);
|
||||
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
|
||||
if (mfill_file_over_size(dst_vma, dst_addr)) {
|
||||
ret = -EFAULT;
|
||||
if (unlikely(offset >= max_off))
|
||||
goto out_unlock;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = -EEXIST;
|
||||
|
@ -211,8 +220,6 @@ static int mfill_atomic_pte_zeropage(pmd_t *dst_pmd,
|
|||
pte_t _dst_pte, *dst_pte;
|
||||
spinlock_t *ptl;
|
||||
int ret;
|
||||
pgoff_t offset, max_off;
|
||||
struct inode *inode;
|
||||
|
||||
_dst_pte = pte_mkspecial(pfn_pte(my_zero_pfn(dst_addr),
|
||||
dst_vma->vm_page_prot));
|
||||
|
@ -220,14 +227,9 @@ static int mfill_atomic_pte_zeropage(pmd_t *dst_pmd,
|
|||
dst_pte = pte_offset_map_lock(dst_vma->vm_mm, dst_pmd, dst_addr, &ptl);
|
||||
if (!dst_pte)
|
||||
goto out;
|
||||
if (dst_vma->vm_file) {
|
||||
/* the shmem MAP_PRIVATE case requires checking the i_size */
|
||||
inode = dst_vma->vm_file->f_inode;
|
||||
offset = linear_page_index(dst_vma, dst_addr);
|
||||
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
|
||||
if (mfill_file_over_size(dst_vma, dst_addr)) {
|
||||
ret = -EFAULT;
|
||||
if (unlikely(offset >= max_off))
|
||||
goto out_unlock;
|
||||
goto out_unlock;
|
||||
}
|
||||
ret = -EEXIST;
|
||||
if (!pte_none(ptep_get(dst_pte)))
|
||||
|
|
Loading…
Reference in New Issue