From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C19364F30C4; Wed, 30 Sep 2026 16:01:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790784073; cv=none; b=uT8Hhl3wEF/pvJRgbSWtbbRY0K2Z/ja/oYC9vmOA09K+LdozOFzehU9E0WK05SrHBBE7PqLztipHX0XHcIf/4SpVeuUBDnpCbT5PuChzHcjiMfbdp8PIrDRkSLNl1OqVj75DuqKdXzDTxwvO7KWWkn6Bdoy1HKC8JgUKikSuowE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790784073; c=relaxed/simple; bh=MuL+BsXv9jg+AfDMvTo+/obDNRChxiy6Q++8oP7CP5c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BVY4B1AIyP+Cr80DlEly9VGN/IVtYpAM73w0vH49XUVmeiE0SWAGRAverYlF0N6v6FKyGjYUSvIBKMzQH4KI7hsJJBbZ6eT4ol2Nw1tPuc0tqcaN+CvcwgkUyoLE+GS/ZectrMMLPm5s4p/hiWD8NfQv1r9fWXdTf+Le1Vkn1DU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=N64tj5/6; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="N64tj5/6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E97851F000FF; Wed, 30 Sep 2026 16:01:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1790784065; bh=HXfS6CCy1AvA7957FkLBSNz1qom5jIcbBcVFL0RmO5w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=N64tj5/6JMDThUYK1m+7Q7Xl6dl9jtKQTHEbiJWEV2nsuxE0Kzdj6rpIg3J6gMrxt w5p6YkLtjLDFBI19Ze6ndYZm3kVQNoOB7zI1dIGf1Zffgi8JaNxtxK/RlhmfvPr2EF t1XH3Nn936+wKN8x6htSILSJlCg15ZP0qsOk9rG4= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, John Paul Adrian Glaubitz , Yangtao Li , linux-fsdevel@vger.kernel.org, Viacheslav Dubeyko , Sasha Levin Subject: [PATCH 6.1 008/982] hfsplus: fix issue of direct writes beyond end-of-file Date: Wed, 30 Sep 2026 17:12:24 +0200 Message-ID: <20260930152416.966689921@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260930152416.775402466@linuxfoundation.org> References: <20260930152416.775402466@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Viacheslav Dubeyko [ Upstream commit 5f63ac80aef2ee6bb58eab62e98c264774872da6 ] The xfstests' test-case generic/729 fails with error: sudo ./check generic/729 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 7.0.0-rc1+ #36 SMP PREEMPT_DYNAMIC Fri Apr 17 12:40:51 PDT 2026 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/729 23s ... [failed, exit status 1]- output mismatch mmap-rw-fault: /mnt/test/mmap-rw-fault.tmp: Input/output error The hfsplus_get_block() only allows creating the next sequential block. It returns -EIO for direct writes beyond EOF. This patch waits for any in-flight DIO on the inode to finish. Then, it extends the file by calling generic_cont_expand_simple() with the goal to guarantee that blockdev_direct_IO() finds all needed blocks already reachable sequentially. And, finally, it flushes and invalidates the DIO range again so the page cache is clean before the direct write begins. sudo ./check generic/729 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 7.0.0-rc1+ #40 SMP PREEMPT_DYNAMIC Thu Apr 16 15:41:03 PDT 2026 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/729 23s ... 32s Ran: generic/729 Passed all 1 tests Closes: https://github.com/hfs-linux-kernel/hfs-linux-kernel/issues/210 cc: John Paul Adrian Glaubitz cc: Yangtao Li cc: linux-fsdevel@vger.kernel.org Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20260417214940.2735557-2-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfsplus/inode.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index f065015f237c4..caf36ed7f590a 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -129,9 +129,44 @@ static ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter) struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; + loff_t isize; size_t count = iov_iter_count(iter); + loff_t end = iocb->ki_pos + count; ssize_t ret; + /* + * The hfsplus_get_block() only allows creating the next sequential block. + * For direct writes beyond EOF, expand the file first. + */ + if (iov_iter_rw(iter) == WRITE && iocb->ki_pos > i_size_read(inode)) { + loff_t start_off, end_off; + loff_t start_page, end_page; + + isize = i_size_read(inode); + + /* + * Wait for any in-flight DIO on this inode to finish before + * calling generic_cont_expand_simple(). + */ + inode_dio_wait(inode); + + ret = generic_cont_expand_simple(inode, iocb->ki_pos); + if (ret) + return ret; + + start_off = isize; + end_off = (end > 0) ? end - 1 : end; + + ret = filemap_write_and_wait_range(mapping, start_off, end_off); + if (ret) + return ret; + + start_page = start_off >> PAGE_SHIFT; + end_page = end_off >> PAGE_SHIFT; + + invalidate_inode_pages2_range(mapping, start_page, end_page); + } + ret = blockdev_direct_IO(iocb, inode, iter, hfsplus_get_block); /* @@ -139,8 +174,7 @@ static ssize_t hfsplus_direct_IO(struct kiocb *iocb, struct iov_iter *iter) * blocks outside i_size. Trim these off again. */ if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { - loff_t isize = i_size_read(inode); - loff_t end = iocb->ki_pos + count; + isize = i_size_read(inode); if (end > isize) hfsplus_write_failed(mapping, end); -- 2.53.0