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 585E55013CE; Wed, 30 Sep 2026 15:32:37 +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=1790782369; cv=none; b=MXz1/2z8kOYUbqnhFs/Ur/ZttIEA6mJPZl+2WhJOmyFOrPPKWD+fTFVq6W9h2c+dnilgHdcb+nvT+cvOp7rdHLrwNicm1whx2fw2IvTZL0r1yOtWmei5+vBX8p9AU4puALPV9tps5GQiTqmGIKxUoQJ3IgS4sK0ApXy1xk6Vx4s= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790782369; c=relaxed/simple; bh=jAteyNSoEqZII2pwr1zGp/e3IY8Y0sT916fBf8TNMj8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bEtyY1GPKM1qFbxE7x/MVqPplpIkAypDeKmo1tnt8tOGFjIflazjvn+AP0NpZgKe1iK72RfHkIQBe00IexbsnMvrKtvrO1mPwN6sAhEC2KXoNvDKGiD60sI1r10h0bGcRS4oru5P0C4LJza3g4b62hhOCq0ywzUUKYBN90oXaK0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=i8N6PLVM; 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="i8N6PLVM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 970DD1F000FF; Wed, 30 Sep 2026 15:32:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1790782357; bh=fMeFodaZr3SePOifRqEs7LTW2oWPr292YrxupEMi3eM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=i8N6PLVM9J6RIhW97D6f3e+CHmYiRmGWgjIOX1mRnarF771RjcbP8tDtL92u/w36w Lk/mWogSVV/tSbcdCTrWwUBofSULalfG54iOC8pjdsj+otVmYJxWOoSD5pKCV8SuV/ 7qrCGwiIcNtwF43nts5pODvAZJ865rZVaNqbjMmg= 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 5.10 006/595] hfsplus: fix issue of direct writes beyond end-of-file Date: Wed, 30 Sep 2026 17:18:19 +0200 Message-ID: <20260930152347.853177797@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260930152347.700140858@linuxfoundation.org> References: <20260930152347.700140858@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 5.10-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 57123b206877c..46ec102e5f393 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -128,9 +128,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); /* @@ -138,8 +173,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