Ackerley Tng <[email protected]> writes:

> 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]/

Instead of avoiding on remove folio, We can just add the freeze check
across the PUNCH_HOLE, So there will be no nested lock anymore. Nested
lock is just with fallocate populate -> kvm_gmem_get_pfn. So this nested
ness will be removed with this update.

~Tarun

>
>>      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