[Devel] [PATCH] fs/fuse kio: satisfy pure FALLOC_FL_KEEP_SIZE immediately
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Dec 25 12:56:55 MSK 2018
On 25.12.2018 12:45, Pavel Butsykin wrote:
>
>
> On 25.12.2018 12:28, Kirill Tkhai wrote:
>> On 24.12.2018 15:54, Pavel Butsykin wrote:
>>> Fallocate without mutex lock can race with setattr size request, as a result,
>>> may be various problems, including incorrectly changed file size. At the same
>>> time pure FALLOC_FL_KEEP_SIZE for vstorage is just nope, so we can immediately
>>
>> man 2 fallocate:
>>
>> "Specifying the FALLOC_FL_ZERO_RANGE flag (available since Linux 3.15) in mode zeros space in the byte range starting at offset and
>> continuing for len bytes. Within the specified range, blocks are preallocated for the regions that span the holes in the file.
>> After a successful call, subsequent reads from this range will return zeros".
>
> Yes, FALLOC_FL_ZERO_RANGE | FALLOC_FL_ZERO_RANGE mode combinations
> should always be under mutex, so we can just move my check before:
> if (inarg->offset >= di->fileinfo.attr.size)
> inarg->mode &= ~FALLOC_FL_ZERO_RANGE;
>
>> So, this patch makes pcs_fuse_kdirect() complete a request without error
>> and without content changing, while userspace thinks the range was zeroed.
>> It's wrong.
>>
>>> complete fallocate with mode == FALLOC_FL_KEEP_SIZE. Also move mutex_is_locked,
>>> since all other mode combinations either have to be under mutex or not valid.
>>>
>>> #VSTOR-19317
>>>
>>> Signed-off-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
>>> ---
>>> fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 6 ++++--
>>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
>>> index de54fedeb5e4..89866370a341 100644
>>> --- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
>>> +++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
>>> @@ -924,9 +924,11 @@ static void pcs_fuse_submit(struct pcs_fuse_cluster *pfc, struct fuse_req *req,
>>> if (inarg->offset >= di->fileinfo.attr.size)
>>> inarg->mode &= ~FALLOC_FL_ZERO_RANGE;
>>>
>>> + if (inarg->mode == FALLOC_FL_KEEP_SIZE)
>>> + break; /* NOPE */
>>
>> This is untidy to add new branch, which makes further "if (inarg->mode & FALLOC_FL_KEEP_SIZE)"
>> check a dead code.
>
> Why? mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE won't pass my
> check, but will pass the check "if (inarg->mode & FALLOC_FL_KEEP_SIZE)",
> it's not a dead code.
Oh, I misread that. Yeah, there is no problem.
>>> +
>>> + WARN_ON_ONCE(!mutex_is_locked(&fi->inode.i_mutex));
>>> if (inarg->mode & (FALLOC_FL_ZERO_RANGE|FALLOC_FL_PUNCH_HOLE)) {
>>> - WARN_ON_ONCE(!mutex_is_locked(&fi->inode.i_mutex));
>>> -
>>> if ((inarg->offset & (PAGE_SIZE - 1)) || (inarg->length & (PAGE_SIZE - 1))) {
>>> r->req.out.h.error = -EINVAL;
>>> goto error;
>>>
More information about the Devel
mailing list