vma.c (3e01310d29a700b99067cb0d6ba21284f2389308) vma.c (fc21959f74bc1138b28e90a02ec224ab8626111e)
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3/*
4 * VMA-specific functions.
5 */
6
7#include "vma_internal.h"
8#include "vma.h"

--- 453 unchanged lines hidden (view full) ---

462 }
463 VM_BUG_ON_MM(bug, mm);
464}
465#endif /* CONFIG_DEBUG_VM_MAPLE_TREE */
466
467/*
468 * vma_expand - Expand an existing VMA
469 *
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3/*
4 * VMA-specific functions.
5 */
6
7#include "vma_internal.h"
8#include "vma.h"

--- 453 unchanged lines hidden (view full) ---

462 }
463 VM_BUG_ON_MM(bug, mm);
464}
465#endif /* CONFIG_DEBUG_VM_MAPLE_TREE */
466
467/*
468 * vma_expand - Expand an existing VMA
469 *
470 * @vmi: The vma iterator
471 * @vma: The vma to expand
472 * @start: The start of the vma
473 * @end: The exclusive end of the vma
474 * @pgoff: The page offset of vma
475 * @next: The current of next vma.
470 * @vmg: Describes a VMA expansion operation.
476 *
471 *
477 * Expand @vma to @start and @end. Can expand off the start and end. Will
478 * expand over @next if it's different from @vma and @end == @next->vm_end.
479 * Checking if the @vma can expand and merge with @next needs to be handled by
480 * the caller.
472 * Expand @vma to vmg->start and vmg->end. Can expand off the start and end.
473 * Will expand over vmg->next if it's different from vmg->vma and vmg->end ==
474 * vmg->next->vm_end. Checking if the vmg->vma can expand and merge with
475 * vmg->next needs to be handled by the caller.
481 *
482 * Returns: 0 on success
483 */
476 *
477 * Returns: 0 on success
478 */
484int vma_expand(struct vma_iterator *vmi, struct vm_area_struct *vma,
485 unsigned long start, unsigned long end, pgoff_t pgoff,
486 struct vm_area_struct *next)
479int vma_expand(struct vma_merge_struct *vmg)
487{
488 struct vm_area_struct *anon_dup = NULL;
489 bool remove_next = false;
480{
481 struct vm_area_struct *anon_dup = NULL;
482 bool remove_next = false;
483 struct vm_area_struct *vma = vmg->vma;
484 struct vm_area_struct *next = vmg->next;
490 struct vma_prepare vp;
491
492 vma_start_write(vma);
485 struct vma_prepare vp;
486
487 vma_start_write(vma);
493 if (next && (vma != next) && (end == next->vm_end)) {
488 if (next && (vma != next) && (vmg->end == next->vm_end)) {
494 int ret;
495
496 remove_next = true;
497 vma_start_write(next);
498 ret = dup_anon_vma(vma, next, &anon_dup);
499 if (ret)
500 return ret;
501 }
502
503 init_multi_vma_prep(&vp, vma, NULL, remove_next ? next : NULL, NULL);
504 /* Not merging but overwriting any part of next is not handled. */
505 VM_WARN_ON(next && !vp.remove &&
489 int ret;
490
491 remove_next = true;
492 vma_start_write(next);
493 ret = dup_anon_vma(vma, next, &anon_dup);
494 if (ret)
495 return ret;
496 }
497
498 init_multi_vma_prep(&vp, vma, NULL, remove_next ? next : NULL, NULL);
499 /* Not merging but overwriting any part of next is not handled. */
500 VM_WARN_ON(next && !vp.remove &&
506 next != vma && end > next->vm_start);
501 next != vma && vmg->end > next->vm_start);
507 /* Only handles expanding */
502 /* Only handles expanding */
508 VM_WARN_ON(vma->vm_start < start || vma->vm_end > end);
503 VM_WARN_ON(vma->vm_start < vmg->start || vma->vm_end > vmg->end);
509
510 /* Note: vma iterator must be pointing to 'start' */
504
505 /* Note: vma iterator must be pointing to 'start' */
511 vma_iter_config(vmi, start, end);
512 if (vma_iter_prealloc(vmi, vma))
506 vma_iter_config(vmg->vmi, vmg->start, vmg->end);
507 if (vma_iter_prealloc(vmg->vmi, vma))
513 goto nomem;
514
515 vma_prepare(&vp);
508 goto nomem;
509
510 vma_prepare(&vp);
516 vma_adjust_trans_huge(vma, start, end, 0);
517 vma_set_range(vma, start, end, pgoff);
518 vma_iter_store(vmi, vma);
511 vma_adjust_trans_huge(vma, vmg->start, vmg->end, 0);
512 vma_set_range(vma, vmg->start, vmg->end, vmg->pgoff);
513 vma_iter_store(vmg->vmi, vma);
519
514
520 vma_complete(&vp, vmi, vma->vm_mm);
515 vma_complete(&vp, vmg->vmi, vma->vm_mm);
521 return 0;
522
523nomem:
524 if (anon_dup)
525 unlink_anon_vmas(anon_dup);
526 return -ENOMEM;
527}
528

--- 1349 unchanged lines hidden ---
516 return 0;
517
518nomem:
519 if (anon_dup)
520 unlink_anon_vmas(anon_dup);
521 return -ENOMEM;
522}
523

--- 1349 unchanged lines hidden ---