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

