Tarun Sahu <[email protected]> writes:

>
> [...snip...]
>
> @@ -273,16 +284,30 @@ static long kvm_gmem_allocate(struct inode *inode, 
> loff_t offset, loff_t len)
>  static long kvm_gmem_fallocate(struct file *file, int mode, loff_t offset,
>                              loff_t len)
>  {
> +     struct inode *inode = file_inode(file);
>       int ret;
> +     int idx;
>
> -     if (!(mode & FALLOC_FL_KEEP_SIZE))
> -             return -EOPNOTSUPP;
> +     idx = srcu_read_lock(&kvm_gmem_freeze_srcu);
> +     if (kvm_gmem_is_frozen(inode)) {
> +             srcu_read_unlock(&kvm_gmem_freeze_srcu, idx);
> +             return -EPERM;
> +     }
>
> -     if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
> -             return -EOPNOTSUPP;
> +     if (!(mode & FALLOC_FL_KEEP_SIZE)) {
> +             ret = -EOPNOTSUPP;
> +             goto out;
> +     }
>
> -     if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len))
> -             return -EINVAL;
> +     if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) {
> +             ret = -EOPNOTSUPP;
> +             goto out;
> +     }
> +
> +     if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len)) {
> +             ret = -EINVAL;
> +             goto out;
> +     }
>

Continuing from [1], this guard is actually meant for PUNCH_HOLE... I
wonder if there could be a deeper refactoring to check when actually
punching a hole, basically the equivalent place as kvm_gmem_get_folio()
in the flow of fallocating.

Will srcu_read_lock() be taken in a nested way for the fallocate case?
It can be taken in a nested way with some intricacies, but maybe if the
freeze check can be done just as the folio is about to be removed (as
described in the above paragraph), it would avoid this nested locking
here.

[1] https://lore.kernel.org/all/[email protected]/

>       if (mode & FALLOC_FL_PUNCH_HOLE)
>               ret = kvm_gmem_punch_hole(file_inode(file), offset, len);
> @@ -291,6 +316,9 @@ static long kvm_gmem_fallocate(struct file *file, int 
> mode, loff_t offset,
>
>       if (!ret)
>               file_modified(file);
> +
> +out:
> +     srcu_read_unlock(&kvm_gmem_freeze_srcu, idx);
>       return ret;
>  }
>
>
> [...snip...]
>

Reply via email to