From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-00364e01.pphosted.com (mx0b-00364e01.pphosted.com [148.163.139.74]) (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 322CD3769F3 for ; Wed, 20 May 2026 20:50:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.139.74 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779310248; cv=none; b=lxybQCG03pPo/kZr8N6NoFnp1B1haBGfatu2bQ5Lnc3LhrcZXxG7ftTtlXombk+CSkXMMfQshLHj+ci6VPcmRCN1RXTfIApc9LLmHh+Af8wa74HpfDrX5N2mPsfic2xkARJvCasDXyiKbQNr0yRyTSkTR7HfaomPeAX2Bw5y0U0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779310248; c=relaxed/simple; bh=sWXCb2voUNh/5RgXFZA32Pq1QXHhhJuRnYDZVKm8gu0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ak9Rh5xZwl4n+iIzQMCdEOj3y4RUkb7Ir18ojVfafLbP+1cUTz11FgEfn0v5cb+2dkhYkfS+/LOqN8AAMtkVSDS3g14mmLHs6f0asbYg0VWZXvC4h+VXvDLJ6fpWlL4ivwPmdEz3TrN2SYoKmDb2ylM/RupN8y2lIb28r12d3sQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=columbia.edu; spf=pass smtp.mailfrom=columbia.edu; dkim=pass (2048-bit key) header.d=columbia.edu header.i=@columbia.edu header.b=RaMC69iL; arc=none smtp.client-ip=148.163.139.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=columbia.edu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=columbia.edu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=columbia.edu header.i=@columbia.edu header.b="RaMC69iL" Received: from pps.filterd (m0499198.ppops.net [127.0.0.1]) by mx0b-00364e01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64KKO5uN2013232 for ; Wed, 20 May 2026 16:50:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=columbia.edu; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pps01; bh=NuYZ UEpkdlDPA/MoPFg1KYmaCTdNZxzaMhmmXnS7n5Y=; b=RaMC69iL96yzOK/lRDf+ 5JstGQzPJTY3tGXJTW72lq1IMm7QXNtfTzTcW2dJzro8iQN+IyGFfOMigEK5kXJC TkrRPLlM6LLPe9Qif+6bs3GDBj8mFTAx3sj1CYxGfo0lwJ12gOLSKkDssy69M3pY kO3SoZGr2BJkk0iYM1n0FLY1CbFqNx1ykfaoWTx5Gb/OxbWLZcWDyIt9kLP3mzNJ cSuJlBH9j4SixMkwpaTYSSyeuOORn178xTCgNO7LWnmh8yB6rbXufNbbbx689Wdj /ONqFgUH4ENnnf762oQfQfPGjfmIXn9BhZXTOIt21neOwtoYd6cH77WqV6mIabu4 Rg== Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by mx0b-00364e01.pphosted.com (PPS) with ESMTPS id 4e9fdn2mvd-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 20 May 2026 16:50:43 -0400 (EDT) Received: by mail-qv1-f70.google.com with SMTP id 6a1803df08f44-8b46c014a26so166734256d6.0 for ; Wed, 20 May 2026 13:50:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779310243; x=1779915043; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=NuYZUEpkdlDPA/MoPFg1KYmaCTdNZxzaMhmmXnS7n5Y=; b=d8NJhct17bbdjW8S/rFO/Bn/lL7c5Jx/om3SNaJWbop9HOBT3ntMZfC8NG/G2ACV3A +BZ2Ag1Szvo3XOz/Zrma3wEwShCy1kR8Yn3W/mBfuqct4YZ4auNkiXvrVYK/rXU4VDU3 w1JU0PgdOjgdNl4Hc5+jfgfN1DtbuvsAh/hFEYZHQpemTkYkZwfUHqgZC7QNxKZHKXCb iy1z4bkt9enSnQqzAu23kO1q89Fpu2lfEQHZIVrZBTTWvVmX9uzO3GEinWFoQdfjQD0e l2+H5D+woscjCXyra/5TUEz3hdpRqW7gQqICslk/5c1/6WB+oE3a31lWr9D2MWzbudyJ 1Ntw== X-Forwarded-Encrypted: i=1; AFNElJ8Aa7HIEhLUoeu0IWsNaz1Wz27g4dDxF+h2HW/kFwoVOpiAiDtcZ7O7Lj44nkGQSdC9ONMIJY9wwzdAZyY=@vger.kernel.org X-Gm-Message-State: AOJu0YxJXLghZfiSEMTV1jkbL2Van7UvAW03+n1y9Kyci0kftWxRLyCd YC/Z0AWp8moamE1PEM/fBOHHnx3Cartadax5sBghHWuGSDFZ/L3N58+U+jVQgx4ckPbUF2TqhTC Sr4eKCaQgXYeLIC1Rei1i7I7MHXFiblRFBbkHGQPaA2I5dTZ0Xvj81I9vviaGmw== X-Gm-Gg: Acq92OEq2H3HFsXJGiHeoMiqVxgYcA3cNxaY1Hvgr0o23gdEQS6aZ5e0SogtLPNWCIE LGTBbDU4oDCEZU3+cpxzbihU1WI7WhZP4FMEm1YW3zrbrnCsf7IBk7b4nF3adv0B8WR+SOdD+6b xGBHak6oU6gXrIT0jJwn49MMv/GV5yfkv+0G9z4KUdFOqqyEvqH/a7qrEgXXNvXANFNT4a7a5Hp PPQiQEF4Bh4WOqUd8BSZBo23j+I9iLHHy457HfPCStbb+Ml8XNU7d/K8ZjHr2KNBKb8C49E1dk3 6/YeX7AKyv9BoAuM0zDRfUqQGxfXb5ay/lvcQNpvddh9cm94564pGOs7CQCq7IvupY09xQ029fD AM70OU62bQ0SDIH4ZR33xw5gHaZwNe92nryCNQMqc6mgctyVopBkksyiwqwrhV5vGP7SVJeMOfe qROg== X-Received: by 2002:a05:620a:258f:b0:8ed:dc5a:f668 with SMTP id af79cd13be357-911d00b7d27mr3703468085a.58.1779310242784; Wed, 20 May 2026 13:50:42 -0700 (PDT) X-Received: by 2002:a05:620a:258f:b0:8ed:dc5a:f668 with SMTP id af79cd13be357-911d00b7d27mr3703462585a.58.1779310242221; Wed, 20 May 2026 13:50:42 -0700 (PDT) Received: from [127.0.1.1] (dyn-160-39-33-242.dyn.columbia.edu. [160.39.33.242]) by smtp.gmail.com with ESMTPSA id af79cd13be357-910bcf37274sm2232692085a.37.2026.05.20.13.50.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 13:50:41 -0700 (PDT) From: Tal Zussman Date: Wed, 20 May 2026 16:49:01 -0400 Subject: [PATCH RFC 10/11] fs: move generic_file_read_iter() to fs/read_write.c Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260520-filemap-split-v1-10-c36ddc2b6cf2@columbia.edu> References: <20260520-filemap-split-v1-0-c36ddc2b6cf2@columbia.edu> In-Reply-To: <20260520-filemap-split-v1-0-c36ddc2b6cf2@columbia.edu> To: "Matthew Wilcox (Oracle)" , Jan Kara , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Alexander Viro , Christian Brauner , Jens Axboe Cc: linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, io-uring@vger.kernel.org, Tal Zussman X-Mailer: b4 0.14.3-dev-d7477 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779310229; l=8508; i=tz2294@columbia.edu; s=20250528; h=from:subject:message-id; bh=sWXCb2voUNh/5RgXFZA32Pq1QXHhhJuRnYDZVKm8gu0=; b=c4SVT0/EKyeLALT++GoCtxlOHEW6EtdwGs6LfnqVwX3PEcOVGXnxyAlvuksJ5kGk//rUF733e +mKRneLOBHUCwxRiU2NqVzX9ZiVWHPnX8ZDbFnwJYl64fBDuIVt5eIF X-Developer-Key: i=tz2294@columbia.edu; a=ed25519; pk=BIj5KdACscEOyAC0oIkeZqLB3L94fzBnDccEooxeM5Y= X-Proofpoint-GUID: aeLt8iQgCiqoEy1ybaKCL8MCakhCun7H X-Authority-Analysis: v=2.4 cv=P/4KQCAu c=1 sm=1 tr=0 ts=6a0e1ea3 cx=c_pps a=oc9J++0uMp73DTRD5QyR2A==:117 a=GaPK54s0Se3oFqK5NkZy0g==:17 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=x7bEGLp0ZPQA:10 a=VkNPw1HP01LnGYTKEx00:22 a=Da8U98TiO7q1upZEImrf:22 a=BpGzv1V74M3SfeTrGa8v:22 a=gH0tmTfNonLjgA-2hfQA:9 a=QEXdDO2ut3YA:10 a=iYH6xdkBrDN1Jqds4HTS:22 X-Proofpoint-ORIG-GUID: aeLt8iQgCiqoEy1ybaKCL8MCakhCun7H X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTIwMDIwMyBTYWx0ZWRfX2I+uxZFo1vDv 1oLcgqBRyIHSQUMd4HZhBecJAQTBmHqu++Tsbi41IbSM5F3oZf7cAwqaaQDmA1ZtFoQkWCvxIZz YKNXil22ySeIJJGu+0Do9aGZWk/eOCgy7GceT9nDQ4xz0zNxhdprHv/8MI0PAu21RzYY4mJK6TE Z+LwL70bW/junNkiXJdwW6gfNo1iyDj2knOJkGEy5MQkMDvyvwEDr1+vK9EIgzf+sYR8XLkqHSP gVdkEhJUqhuJW0Joor+IrJtdxZrhrP0Uw/YWHjVK3p/usm0T6hw+gFNlCaX4Uxpmt2VaC8LNoWc hGIlVxogqzBKwAzMUumkBrrLQ+skYsiRt+8V4PbrOcg7S1aNLu/lPGWrQxcsArSRGXTR4zgSscn c3bJ1i58Mn1yQIHBSVG2bOCAm2MhuAuyU8x5HIppCikvXyJQEU3yTBzMjIcx6IRMMQMVaBoBogh bMdRXDj0ofrPLigLmHg== X-Proofpoint-Virus-Version: vendor=nai engine=6900 definitions=11792 signatures=596817 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 suspectscore=0 impostorscore=10 malwarescore=0 phishscore=0 adultscore=0 lowpriorityscore=10 spamscore=0 priorityscore=1501 bulkscore=10 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605200203 generic_file_read_iter() and its kiocb_write_and_wait() helper are VFS-level read functions: Their callers are filesystems, and their job is to glue direct I/O or the page cache (filemap_read) to a struct kiocb and iov_iter caller. Move both to fs/read_write.c, alongside vfs_iter_read. Drop the extern from generic_file_read_iter()'s declaration and reflow the generic_file_read_iter() definition to fit on one line too. Signed-off-by: Tal Zussman --- fs/read_write.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 3 +- include/linux/pagemap.h | 1 - mm/filemap.c | 82 ------------------------------------------------- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 50bff7edc91f..59ceea85c163 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -989,6 +989,88 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos, } EXPORT_SYMBOL(vfs_iter_write); +int kiocb_write_and_wait(struct kiocb *iocb, size_t count) +{ + struct address_space *mapping = iocb->ki_filp->f_mapping; + loff_t pos = iocb->ki_pos; + loff_t end = pos + count - 1; + + if (iocb->ki_flags & IOCB_NOWAIT) { + if (filemap_range_needs_writeback(mapping, pos, end)) + return -EAGAIN; + return 0; + } + + return filemap_write_and_wait_range(mapping, pos, end); +} +EXPORT_SYMBOL_GPL(kiocb_write_and_wait); + +/** + * generic_file_read_iter - generic filesystem read routine + * @iocb: kernel I/O control block + * @iter: destination for the data read + * + * This is the "read_iter()" routine for all filesystems + * that can use the page cache directly. + * + * The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall + * be returned when no data can be read without waiting for I/O requests + * to complete; it doesn't prevent readahead. + * + * The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O + * requests shall be made for the read or for readahead. When no data + * can be read, -EAGAIN shall be returned. When readahead would be + * triggered, a partial, possibly empty read shall be returned. + * + * Return: + * * number of bytes copied, even for partial reads + * * negative error code (or 0 if IOCB_NOIO) if nothing was read + */ +ssize_t generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + size_t count = iov_iter_count(iter); + ssize_t retval = 0; + + if (!count) + return 0; /* skip atime */ + + if (iocb->ki_flags & IOCB_DIRECT) { + struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + + retval = kiocb_write_and_wait(iocb, count); + if (retval < 0) + return retval; + file_accessed(file); + + retval = mapping->a_ops->direct_IO(iocb, iter); + if (retval >= 0) { + iocb->ki_pos += retval; + count -= retval; + } + if (retval != -EIOCBQUEUED) + iov_iter_revert(iter, count - iov_iter_count(iter)); + + /* + * Btrfs can have a short DIO read if we encounter + * compressed extents, so if there was an error, or if + * we've already read everything we wanted to, or if + * there was a short read because we hit EOF, go ahead + * and return. Otherwise fallthrough to buffered io for + * the rest of the read. Buffered reads will not work for + * DAX files, so don't bother trying. + */ + if (retval < 0 || !count || IS_DAX(inode)) + return retval; + if (iocb->ki_pos >= i_size_read(inode)) + return retval; + } + + return filemap_read(iocb, iter, retval); +} +EXPORT_SYMBOL(generic_file_read_iter); + static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, unsigned long vlen, loff_t *pos, rwf_t flags) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 776cc82932a7..c0151ced8e7a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3055,7 +3055,8 @@ extern int generic_write_check_limits(struct file *file, loff_t pos, extern int generic_file_rw_checks(struct file *file_in, struct file *file_out); ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *to, ssize_t already_read); -extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); +ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); +int kiocb_write_and_wait(struct kiocb *iocb, size_t count); extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index f86a550ad516..46cefd552a51 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -59,7 +59,6 @@ int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end); int filemap_check_errors(struct address_space *mapping); void __filemap_set_wb_err(struct address_space *mapping, int err); -int kiocb_write_and_wait(struct kiocb *iocb, size_t count); static inline int filemap_write_and_wait(struct address_space *mapping) { diff --git a/mm/filemap.c b/mm/filemap.c index 079f9c3ac8a2..db7c53cd681b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2251,22 +2251,6 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, } EXPORT_SYMBOL_GPL(filemap_read); -int kiocb_write_and_wait(struct kiocb *iocb, size_t count) -{ - struct address_space *mapping = iocb->ki_filp->f_mapping; - loff_t pos = iocb->ki_pos; - loff_t end = pos + count - 1; - - if (iocb->ki_flags & IOCB_NOWAIT) { - if (filemap_range_needs_writeback(mapping, pos, end)) - return -EAGAIN; - return 0; - } - - return filemap_write_and_wait_range(mapping, pos, end); -} -EXPORT_SYMBOL_GPL(kiocb_write_and_wait); - int filemap_invalidate_pages(struct address_space *mapping, loff_t pos, loff_t end, bool nowait) { @@ -2302,72 +2286,6 @@ int kiocb_invalidate_pages(struct kiocb *iocb, size_t count) } EXPORT_SYMBOL_GPL(kiocb_invalidate_pages); -/** - * generic_file_read_iter - generic filesystem read routine - * @iocb: kernel I/O control block - * @iter: destination for the data read - * - * This is the "read_iter()" routine for all filesystems - * that can use the page cache directly. - * - * The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall - * be returned when no data can be read without waiting for I/O requests - * to complete; it doesn't prevent readahead. - * - * The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O - * requests shall be made for the read or for readahead. When no data - * can be read, -EAGAIN shall be returned. When readahead would be - * triggered, a partial, possibly empty read shall be returned. - * - * Return: - * * number of bytes copied, even for partial reads - * * negative error code (or 0 if IOCB_NOIO) if nothing was read - */ -ssize_t -generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) -{ - size_t count = iov_iter_count(iter); - ssize_t retval = 0; - - if (!count) - return 0; /* skip atime */ - - if (iocb->ki_flags & IOCB_DIRECT) { - struct file *file = iocb->ki_filp; - struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - - retval = kiocb_write_and_wait(iocb, count); - if (retval < 0) - return retval; - file_accessed(file); - - retval = mapping->a_ops->direct_IO(iocb, iter); - if (retval >= 0) { - iocb->ki_pos += retval; - count -= retval; - } - if (retval != -EIOCBQUEUED) - iov_iter_revert(iter, count - iov_iter_count(iter)); - - /* - * Btrfs can have a short DIO read if we encounter - * compressed extents, so if there was an error, or if - * we've already read everything we wanted to, or if - * there was a short read because we hit EOF, go ahead - * and return. Otherwise fallthrough to buffered io for - * the rest of the read. Buffered reads will not work for - * DAX files, so don't bother trying. - */ - if (retval < 0 || !count || IS_DAX(inode)) - return retval; - if (iocb->ki_pos >= i_size_read(inode)) - return retval; - } - - return filemap_read(iocb, iter, retval); -} -EXPORT_SYMBOL(generic_file_read_iter); /* * Splice subpages from a folio into a pipe. -- 2.39.5