From nobody Sat Jul 25 23:03:35 2026 Received: from mail-pf1-f180.google.com (mail-pf1-f180.google.com [209.85.210.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA104315D29 for ; Sat, 11 Jul 2026 20:59:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803561; cv=none; b=ppRxuuxspiVBWEAZtFtfTeZ4s/6IRipVNrtqqZKVWUziqTLmwGzQqoT4ld91ZGafEBIGbJFkxUgu6DGcLN4pBhe9LeVxXfNF3hSfnK74tpXrvvCI5ph2FH2hyWr2O7iz4Vhy0Eqk0NNyCX+PvpgGGpgBLwktMKN6f0Xn91Dev5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803561; c=relaxed/simple; bh=eimG9XEE0URF2SzaH136zk48Fc7acApR5oefaesDiWA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kQZC7Nu77NIZP3Sh6G/IfQogInoK4MORLzjJVL6lEBtfmyG6gULRw0+RhwUi69C9o1dUMxxRm45P7QwwVAnEbMH8w3pOktggR60Jr6WNaFB14sYj1RdCDHL9V1gxRheJWYTFl0Thrb7+2NzshTYi2W3kt3f48L/iXWMffF5oHPQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Y66xVp4O; arc=none smtp.client-ip=209.85.210.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Y66xVp4O" Received: by mail-pf1-f180.google.com with SMTP id d2e1a72fcca58-842338c18e0so1532858b3a.1 for ; Sat, 11 Jul 2026 13:59:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783803559; x=1784408359; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OJJSoaUqwCHC2v0nACew6MdUN87VPmOrK8EaocGT768=; b=Y66xVp4O8bggq/neX8dAbEtaCo67rlP6oLdcsP618W8U9cS4v/d07+qtavRxJD98k1 LWOtTtWp+OXAMBc2ZCNhKFS/qOe3BNSrfr1BVC1+KucVFNXtaxd1+89KAJBAIwtGF6QQ MKOh4lrgXFgbbIv6PCB6qCP6+1pIHljFawz8xjXIrTez7hPH6DAyOU/KBBEkxwSKbFUb UBjev+l+u0LNvicpAyZctustHcIPDPu0J/OCIEv6ogwjB1xE8eyf3yo/48WgUNOIutze 9nP/0h73WxbZzDLMFCFinnKu5eerBTasHSSfNmmuogO9Ldz2E/jCk40NUbxdWDd+DiBe 3kfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783803559; x=1784408359; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OJJSoaUqwCHC2v0nACew6MdUN87VPmOrK8EaocGT768=; b=K+dyzgq6MIMHyDKxub82VBTc+pK0ILypAklGpXcPc0In9YPXtOJR5CeuXeG783EZCN PjgIs+d+fS2PPYlvzzosIWToBU06CZyDklO+IN8+/UcHt6r5JHQq+0QAZETcx7JoZVdv FKxSjpP+dwxa1lLd9Vqr0+RXy+jtZOQxlxl/DNqb/1zkc1KwvtFLkBnBtOgFrH40w30o L3uKPdOAn04A/f2H3RlI67gdxF6eFxakwSNZfx3Nv3f/3ZwFrneDqv4O6xqePiZL/5uJ BPyKJ2XISYUz97TdYJnpC/e9Bw7B/iivuUfL3hkke+c5kMmz9Lg2IftCwqajG7u8V8W3 dk/Q== X-Gm-Message-State: AOJu0YzB+CgrVBfpXEm9qY58SqNn+U2rGw4lexQTJweRsY7eXqQTy1dL CWhAo/BWqD7q6jiJMGWt9bzCRBcLBUqgvbf4PlHIwIJ1W++oFy0BpqkO X-Gm-Gg: AfdE7cmxDl/szghTOqFzMFu4c9qn/HPA7YqV6BwoHOS+ACuL8pdkzJNd0moqpKpY63r aBmwOk7W4PtdPJb8gFkw4dx5DP66GuvWdZ+HinWZIh1cYjOD1Y1ZlFPNJN1JcQatqqNkOafRGZ5 aBcMYGhM8evCvP84nhZTC0mXb7MkVj/QKDeWfPL3HWRRd0sXZmUGalTRVsFehViAZAoWdVW+md9 zZhydJpE2rI7hM3VdaURBr4KNsWjk2sa3WxBV86bZDeX2QD5TnGDtZr5VU0Dw04/EJUQgVpgwS9 lMGysZasGUWUNEaZvsuMa7z4xJ/F5/jRfgIzqnDBhfCzbhV+q4vpPE7JCv4kDPUQ4gabLxqLJ+i nig4wSbnrTBBdVeCcSJiZJzw6UD5+z9kJoR89keHhjNWYmtpduvFOAizJAct7mKE= X-Received: by 2002:a05:6a00:3494:b0:842:48ae:1d6c with SMTP id d2e1a72fcca58-8488965bcdfmr3290961b3a.24.1783803558981; Sat, 11 Jul 2026 13:59:18 -0700 (PDT) Received: from nineveh.sos.local ([131.191.24.68]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84880a44feasm2092057b3a.20.2026.07.11.13.59.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 13:59:18 -0700 (PDT) From: Jeremy Bingham To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, brauner@kernel.org, jkoolstra@xs4all.nl, jack@suse.cz, djwong@kernel.org, viro@zeniv.linux.org.uk, Jeremy Bingham Subject: [PATCH v3 1/5] iomap: add iomap_symlink_write Date: Sat, 11 Jul 2026 13:59:05 -0700 Message-ID: <570b47ec69233efcdde6644fc11bc5a8af6a9577.1783707063.git.jbingham@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new iomap_symlink_write function as an iomap based equivalent to page_symlink found in fs/namei.c. This implementation was suggested by Darrick J. Wong, who also provided the initial implementation that I only needed to change slightly to get working. Suggested-by: Darrick J. Wong Signed-off-by: Jeremy Bingham --- fs/iomap/buffered-io.c | 31 +++++++++++++++++++++++++++++++ include/linux/iomap.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 276720bc18dc..6f3f79fdbd8b 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -2066,3 +2066,34 @@ iomap_writepages(struct iomap_writepage_ctx *wpc) return error; } EXPORT_SYMBOL_GPL(iomap_writepages); + +int iomap_symlink_write(struct inode *inode, const char *target, int len, + const struct iomap_ops *ops, + const struct iomap_write_ops *write_ops, void *private) +{ + struct kvec vec =3D { + .iov_base =3D (void *)target, + .iov_len =3D len, + }; + struct iomap_iter iter =3D { + .inode =3D inode, + .pos =3D 0, + .len =3D len, + .flags =3D IOMAP_WRITE, + .private =3D private, + }; + struct iov_iter iov; + int ret; + + iov_iter_kvec(&iov, ITER_SOURCE, &vec, 1, len); + + while ((ret =3D iomap_iter(&iter, ops)) > 0) + iter.status =3D iomap_write_iter(&iter, &iov, write_ops); + + if (unlikely(iter.pos =3D=3D 0)) + return ret; + + mark_inode_dirty(inode); + return 0; +} +EXPORT_SYMBOL_GPL(iomap_symlink_write); diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 56b43d594e6e..9274fa256bc9 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -393,6 +393,10 @@ loff_t iomap_seek_data(struct inode *inode, loff_t off= set, sector_t iomap_bmap(struct address_space *mapping, sector_t bno, const struct iomap_ops *ops); =20 +int iomap_symlink_write(struct inode *inode, const char *target, int len, + const struct iomap_ops *ops, + const struct iomap_write_ops *write_ops, void *private); + /* * Flags for iomap_ioend->io_flags. */ --=20 2.47.3 From nobody Sat Jul 25 23:03:35 2026 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E6F0313E34 for ; Sat, 11 Jul 2026 20:59:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803565; cv=none; b=IGKZa1Dm/HVFh0vS+kNcAeqnF7tWceYmMN3EizWHbWEaMs7qFVHn2ynqFngCDsvn/8s9papar6FA69Ub21jAfrBGIeIZYX0htKJCS8o+GBX/4aG2MwHTyivZQolM/CN0UBE58XmjgoIuwtrmJTlE80lsX1BG07Rs/LeCiAOmO2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803565; c=relaxed/simple; bh=kw0OMQMrjvlSwGKPOoDzAWrf75ZhL3wz/Mmj/2mK3do=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X2yVw1EuU3bnmjlm5aw6YUQ8S5wgrxq1jOXEcYaTD7778+lO+r+mTEJ+Xgimz63mUpgJB5ovxwXROiqNqiP7JvjAKHLjymfRm/siCB8tcvrCAUauItRWNsXgIQSdCEXhQW9aqScFS10u7gTXgqRqahmSzFZY0g6rrzg3EBaOoY8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=a2WghIb5; arc=none smtp.client-ip=209.85.210.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="a2WghIb5" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-8485b358552so2145349b3a.2 for ; Sat, 11 Jul 2026 13:59:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783803563; x=1784408363; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=e6t8DGVkdCLYUd0OR5aV/ertEnot2rifntCQT4Agz04=; b=a2WghIb5NZ2KYgmDdfhNud/2TV89IhAV3nTHRBAHvoHHRB/k4w7re3CW+YLJhNV+yL scm510K4hoJkkoiJ9PhJM49+0mijT77i2OTzqkOwChCsfAW4YaEFLwsCK62voSleviTK fjEB1llmd5KNpGoEmJq3l1BiIIu12GQAT0lJNHYFe1NA7iwha3F2eOQUdyTGWXA41gA0 bzCP7hkPjf9CDUFjdKndiGiaElDOhhrEZcu5x/GCX4O0qjwT3vQihRlF/kTMdIfF0MqY 85Yx8SPVhdQv73+SbI5getizQawVQYzzhZ3djhGnIY0jm373Oru39PwhXqgV/qlbVBoB nbJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783803563; x=1784408363; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=e6t8DGVkdCLYUd0OR5aV/ertEnot2rifntCQT4Agz04=; b=ZbTXliVmN5Nm/ofp8JCw9WMgVzNJtOi3Q6FzrcsQZX3tHA6CnOLU/3hGrPoin20AlP R0hIJSqUa+KFw1o9xHsOy17daaJMEHCkyY79RO2zR6gjYfS3fxuB6nC+IAzWZjNz1CZz FHBTj7zh+KXmJejEDBrIqkv8qJPgT+fZ2ZbcJQORYOcWvZX8NVvADwTM375+YXtrhl7D BqPT6reI/95+gorU6i59Rb366hm0BnchGW9xamGeJ/FPVHb1m9EU++eNOA0ZCTZRr068 MtWbWkt0ySxm6xk/8osX8qnUNzdXQK9Q3evLAdyTvkwDlyLLIxBFL6iGh+B2as5T6DgG aWFA== X-Gm-Message-State: AOJu0YwIjR9lzXLJ9eGUzEwl40sABOtRDEDCuEWu4Q0Zcc/DiGesgQh4 xbpfQv6CpHIdftPlV5SBMuDfCvQFLsG8u/rwVai+GfXFBbh3qIvZRa6q X-Gm-Gg: AfdE7ckZUM22StlWxlu9eN5bJqRW8AdIcKqYbNurGBXaDBIIG2x7dUEcgP8GHH9a/Ti D1XCZn++jNhhSzQPXJiMpPQhjpCXjwmoeWhEbgZ/eMQ82rjD7/jjpIkizD3By1dQGsJtSqoP0Jq Tz95pL5c2vVDBXwNa5ckZHuoLnJlQY7U1g7QsKd6du/9P5JNtjS3qePkQAxHtvBC9ouw76mlluE Ao/y3K7HkNm4sbTPu2HoBOWrV2S5vgz1ScwcaWzW/oDrPQL1QI8zM2Sy0ixNKA8M7q80xVdr/Fq N0UlkQNLuks0CvEl+vHw8sVDE6Zn3AQkhbrc0lNdtfwJ9YnihycqlU8v8CGM8X942oXjk8xbu+u AYaiQgrfBEeUzxQnQH8eSHv2GVoeQUdjSacRIPz1AJNvD/U6WbhrfBkEWP3zZHRw= X-Received: by 2002:a05:6a00:802:b0:848:2f84:734 with SMTP id d2e1a72fcca58-8488990c921mr4151313b3a.71.1783803562857; Sat, 11 Jul 2026 13:59:22 -0700 (PDT) Received: from nineveh.sos.local ([131.191.24.68]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84880a44feasm2092057b3a.20.2026.07.11.13.59.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 13:59:22 -0700 (PDT) From: Jeremy Bingham To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, brauner@kernel.org, jkoolstra@xs4all.nl, jack@suse.cz, djwong@kernel.org, viro@zeniv.linux.org.uk, Jeremy Bingham Subject: [PATCH v3 2/5] minix: add base iomap begin/end functions Date: Sat, 11 Jul 2026 13:59:06 -0700 Message-ID: <555d199291b37e5c1241df648b3adcd760c1fca6.1783707063.git.jbingham@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Adds a new file, iomap.c, to fs/minix. This provides minix_iomap_begin, which is the iomap-based version of get_block in itree_common.c. It also provides minix_iomap_end, which is a no-op but required by the iomap_ops struct. This also undoes the nest of gotos inherited from get_block and uses a set of helper functions instead. Suggested-by: Darrick J. Wong Signed-off-by: Jeremy Bingham --- fs/minix/iomap.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 fs/minix/iomap.c diff --git a/fs/minix/iomap.c b/fs/minix/iomap.c new file mode 100644 index 000000000000..90e016aaa01e --- /dev/null +++ b/fs/minix/iomap.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * iomap functions for minix. + */ + +static inline void minix_chain_cleanup(Indirect *chain, Indirect *partial) +{ + while (partial > chain) { + brelse(partial->bh); + partial--; + } +} + +static inline void minix_iomap_set_mapped(struct iomap *iomap, sector_t ph= ys, + unsigned int blkbits, sector_t iblock) +{ + iomap->type =3D IOMAP_MAPPED; + iomap->addr =3D (u64)phys << blkbits; + iomap->length =3D 1 << blkbits; + iomap->offset =3D (u64)iblock << blkbits; +} + +static inline void minix_iomap_set_hole(struct iomap *iomap, + unsigned int blkbits, sector_t iblock) +{ + iomap->type =3D IOMAP_HOLE; + iomap->addr =3D IOMAP_NULL_ADDR; + iomap->length =3D 1 << blkbits; + iomap->offset =3D (u64)iblock << blkbits; +} + +/* + * minix_iomap_begin - map a file range to disk blocks. It acts as a repla= cement + * for get_block in itree_common.c, at least in the important ways, and is + * adapted from it, but it uses iomap instead of buffer_head. + */ +static int minix_iomap_begin(struct inode *inode, loff_t offset, loff_t le= ngth, + unsigned int flags, struct iomap *iomap, struct iomap *srcmap) +{ + struct super_block *sb =3D inode->i_sb; + unsigned int blkbits =3D sb->s_blocksize_bits; + sector_t iblock =3D offset >> blkbits; + int create =3D flags & IOMAP_WRITE; + + int offsets[DEPTH]; + Indirect chain[DEPTH]; + Indirect *partial; + int depth =3D block_to_path(inode, iblock, offsets); + int left; + int err =3D -EIO; + + sector_t phys; + + /* block is beyond max file size */ + if (depth =3D=3D 0) + return -EINVAL; + + iomap->bdev =3D inode->i_sb->s_bdev; + +reread: + partial =3D get_branch(inode, depth, offsets, chain, &err); + + /* Simplest case - block found, no allocation needed */ + if (!partial) { + iomap->flags =3D 0; + phys =3D block_to_cpu(chain[depth - 1].key); + partial =3D chain+depth-1; + minix_iomap_set_mapped(iomap, phys, blkbits, iblock); + minix_chain_cleanup(chain, partial); + return err; + } + + /* Next simple case - plain lookup or failed read of indirect block */ + if (!create || err =3D=3D -EIO) { + minix_iomap_set_hole(iomap, blkbits, iblock); + minix_chain_cleanup(chain, partial); + return err; + } + + /* + * This is held over from the original get_block logic, where it + * acted as a guard in case truncate() deleted blocks from under that + * function. There should not be a race with iomap operations, but + * we're retaining the defensive coding here to be extra safe just in + * case. + */ + if (err =3D=3D -EAGAIN) { + minix_chain_cleanup(chain, partial); + goto reread; + } + + left =3D (chain + depth) - partial; + err =3D alloc_branch(inode, left, offsets + (partial - chain), partial); + if (err) { + minix_chain_cleanup(chain, partial); + return err; + } + + if (splice_branch(inode, chain, partial, left) < 0) { + minix_chain_cleanup(chain, partial); + goto reread; + } + + /* Successful allocation, mapping it. */ + iomap->flags =3D IOMAP_F_NEW; + phys =3D block_to_cpu(chain[depth - 1].key); + minix_iomap_set_mapped(iomap, phys, blkbits, iblock); + minix_chain_cleanup(chain, partial); + + return err; +} + +/* + * minix_iomap_end ends up being a nop; since minix doesn't have any exten= ts or + * transactions to worry about, there isn't anything to update here. The o= n-disk + * indirect blocks get dirtied in minix_iomap_begin. + */ +static int minix_iomap_end(struct inode *inode, loff_t offset, loff_t leng= th, + ssize_t written, unsigned int flags, struct iomap *iomap) +{ + return 0; +} --=20 2.47.3 From nobody Sat Jul 25 23:03:35 2026 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4CED317160 for ; Sat, 11 Jul 2026 20:59:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803568; cv=none; b=rvP1pc72pDw5vNwin6TioGsUzggxoKZV0i93TCwdm18Qmg7t6EmpWVyeVp8gEG1ufONN6TCN4XpD2ms17cd1QlER9IWPfx78Y7Pjq3ES9BdCfI0892ntGet7HJEnYXCQS5u+Hj7nWWEB9FW05oO4y0Z7FUHy1KDQ9MCDHekUgLE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803568; c=relaxed/simple; bh=boYaWVocRfbrcKGoZTui9P+AmxLmomIzyo6TpT4aqOg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IEzAnzUTsZBgaCRYfJHD/RMEz8zfAPl0deBK+KVuNezoQFbs/kxxp4P6SB9d8lt6MwTAOgwx1lS6VCHKP6mJdmdLb2fQTYW9DZX4qATpv+s8cT02Q6/8TZS7vhllLUOcxLBsHhyCp2aNlk8OlZqere2ZEnBPuc4fSr63sTk8/Zw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NRqvV3TN; arc=none smtp.client-ip=209.85.215.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NRqvV3TN" Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-c85b73ffb52so976609a12.3 for ; Sat, 11 Jul 2026 13:59:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783803566; x=1784408366; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=rE/h4apMqet61W9gglIUxnNvssBld20bJ32fR1C6+VY=; b=NRqvV3TNnWDkDeg1zcQttOtt4KsavLT2dWmMZFJeYC7lh9N7nkfdkjxpOhIdwP3G4X XDo8tdCxHhvZ/zx3SCmMMROImHclli2FoXAKTIhxK0wgXXS3+37Qcu1vq9QJkPMa7MHG DSNm7GnstWWLWfqh68fUPP0odD1Fhmjm9pUSDUVWLRqLDDuL5lllY6gkxy3WHbgHIk3K KUBH2ybcIRsk3grXVkAOT4L73cXJ7GX5rmbbF59IAMcGV4hk4sRkny2Tp7Fmf1odLkz5 Phqz3o5YMoMb0fJFtJznQyYIojFzo9cOCTAtTFpHXusc0eSxjOxdbtfMO5wfovHnDSCU SaqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783803566; x=1784408366; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=rE/h4apMqet61W9gglIUxnNvssBld20bJ32fR1C6+VY=; b=GtSQJAUHKhTN4XyyGD4nH2S7em0bq7z8KPHOlEKfOhHnM2794Q/h/dUMu+7xnP+bsr APTZnJ/mVc1xxmvso7UqAqYjxxmFuJJaQG853eo2A1Z94jt1YeJJOlKaapmiMVScP9mm XlhaNQhOhHLB3kASp9jUGJZZPyMG1Uzc0+jzbzORp7ZNlJnd+bDdFRyZR2/eAPIbnR5P oR2HYgWrBfk2tG6sCjJeuZbefK3dJsd8rtawHj9Ky2a8DYksuNK8OtPSsmDiooE6ua7L fs909cQ7Z1ca+ow+bXfdxY4RHUz/LZrMIjvZTeRJnYVxOStbttFE+GSpMQzzb1Eap8Xq vObg== X-Gm-Message-State: AOJu0YykqP107AN18ONOcmY0DWGvFYZyNyMsZwvZw+EVNYkPmkDR53S/ fyx79WjxOm7k4YFjKDSOpSF9KG37g8X54ByIudbAO7Hml9K8XiLwQx54 X-Gm-Gg: AfdE7cmezXDdawnQz9mKt1B5pxpZdPtTsfRe9C0EgERj3iCW0joUirKb17GVkwh8+f2 ZCUxDb0VcrUSgV6sFLhmTBJ0H0o+er8evCvB76NQBeZPfyF+lqujA56XOCmd2uhEOzDBg8KPxZ4 h2/J4bSzOLVtvvUau4F70YNWSCRSwL+6I61Fp5mrNOtQUdE82IY7IYigBRCFKvFl6LUHEDamZJd irJ9ixGShjKBL9QLxm+/4ncgBDTrHmlMYkSkz1tEFkLViqTzP6c+SW0QFxZdbgQ80eHBAP3CCin 1wiTk1TUYCq4Y+C3J23NccB8Sv5Kujl8Mi3jaV7qPPtkUNnPvCsJ/GjP+eLL3lSKaNU78Qz5gXy aJoCtUjQxdnCPpbfrezvAwsCBIu0yPMCZOlQzlpVk2QDymMmj1nz5v5Bi/36xuJ0= X-Received: by 2002:a05:6a00:893:b0:847:5ec4:9a1d with SMTP id d2e1a72fcca58-848897aca47mr3628664b3a.62.1783803566128; Sat, 11 Jul 2026 13:59:26 -0700 (PDT) Received: from nineveh.sos.local ([131.191.24.68]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84880a44feasm2092057b3a.20.2026.07.11.13.59.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 13:59:25 -0700 (PDT) From: Jeremy Bingham To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, brauner@kernel.org, jkoolstra@xs4all.nl, jack@suse.cz, djwong@kernel.org, viro@zeniv.linux.org.uk, Jeremy Bingham Subject: [PATCH v3 3/5] minix: update itree* files to add iomap functions Date: Sat, 11 Jul 2026 13:59:07 -0700 Message-ID: <82e67921d4515cc88ad7df09bc3ccb8dffce0b89.1783707063.git.jbingham@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that iomap.c is in place, update itree_v1.c, itree_v2.c, and itree_common.c to use iomap. This also updates the exports in minix.h, adds a convenient helper function to get the right version of minix_iomap_ops, and exports the previously static minix_aops struct from inode.c. There are a couple of odd things in here that need to be explicitly called out and explained: First, in itree_common.c there is now a check on inode->i_mapping->a_ops where if it is equal to &minix_aops. If it is, it calls iomap_truncate_page; otherwise, it calls block_truncate_page. This is because unlike everything else directory operations still use buffer_heads and have their own address_space_operations struct. Second, instead of standing alone iomap.c is #included into itree_v1.c and itree_v2.c the same way itree_common.c is. This is an existing pattern that has been present in this module as far back as the git history goes to accomodate the different block pointer sizes and number of indirect block levels the different versions of the minix filesystem has. The way it is now does look very strange, but it avoids massive changes that might not be appreciated. Signed-off-by: Jeremy Bingham --- fs/minix/inode.c | 2 +- fs/minix/itree_common.c | 11 ++++++++++- fs/minix/itree_v1.c | 25 ++++++++++++++++++++++++- fs/minix/itree_v2.c | 17 ++++++++++++++++- fs/minix/minix.h | 22 ++++++++++++++++++++-- 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/fs/minix/inode.c b/fs/minix/inode.c index c30cc590698d..d5ba72f51049 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -490,7 +490,7 @@ static sector_t minix_bmap(struct address_space *mappin= g, sector_t block) return generic_block_bmap(mapping,block,minix_get_block); } =20 -static const struct address_space_operations minix_aops =3D { +const struct address_space_operations minix_aops =3D { .dirty_folio =3D block_dirty_folio, .invalidate_folio =3D block_invalidate_folio, .read_folio =3D minix_read_folio, diff --git a/fs/minix/itree_common.c b/fs/minix/itree_common.c index c3cd2c75af9c..5a8b73a7beda 100644 --- a/fs/minix/itree_common.c +++ b/fs/minix/itree_common.c @@ -311,7 +311,16 @@ static inline void truncate (struct inode * inode) long iblock; =20 iblock =3D (inode->i_size + sb->s_blocksize -1) >> sb->s_blocksize_bits; - block_truncate_page(inode->i_mapping, inode->i_size, get_block); + + /* Depending on what address space operations are being used by the + * inode being truncated, we need to either call iomap_truncate_page or + * block_truncate_page. + */ + if (inode->i_mapping->a_ops =3D=3D &minix_aops) + iomap_truncate_page(inode, inode->i_size, NULL, + minix_iomap_ops_ver(inode), NULL, NULL); + else + block_truncate_page(inode->i_mapping, inode->i_size, get_block); =20 n =3D block_to_path(inode, iblock, offsets); if (!n) diff --git a/fs/minix/itree_v1.c b/fs/minix/itree_v1.c index 1fed906042aa..58c29f4443d3 100644 --- a/fs/minix/itree_v1.c +++ b/fs/minix/itree_v1.c @@ -49,6 +49,18 @@ static int block_to_path(struct inode * inode, long bloc= k, int offsets[DEPTH]) } =20 #include "itree_common.c" +/* NOTA BENE: + * + * This is icky to me, but at the same time having it be a standalone C fi= le + * that's compiled to object form and linked separately like one would thi= nk is + * much nastier in minix because of the different versions of the minix fs= that + * have some very, very different aspects, like the size of block_t. I don= 't + * like it, but since minix already has this pattern where a common itree = file + * is included in the itree_v1 and itree_v2(and v3) files, I'm including i= omap.c + * in these files as well. It does at least avoid exporting some currently + * static functions that aren't needed anywhere but itree_common.c and iom= ap.c. + */ +#include "iomap.c" =20 int V1_minix_get_block(struct inode * inode, long block, struct buffer_head *bh_result, int create) @@ -61,7 +73,18 @@ void V1_minix_truncate(struct inode * inode) truncate(inode); } =20 -unsigned V1_minix_blocks(loff_t size, struct super_block *sb) +unsigned int V1_minix_blocks(loff_t size, struct super_block *sb) { return nblocks(size, sb); } + +int V1_minix_iomap_begin(struct inode *inode, loff_t offset, loff_t length, + unsigned int flags, struct iomap *iomap, struct iomap *srcmap) +{ + return minix_iomap_begin(inode, offset, length, flags, iomap, srcmap); +} + +const struct iomap_ops V1_minix_iomap_ops =3D { + .iomap_begin =3D V1_minix_iomap_begin, + .iomap_end =3D minix_iomap_end, +}; diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c index 9d00f31a2d9d..fc7a5ae8fa1c 100644 --- a/fs/minix/itree_v2.c +++ b/fs/minix/itree_v2.c @@ -57,6 +57,10 @@ static int block_to_path(struct inode * inode, long bloc= k, int offsets[DEPTH]) } =20 #include "itree_common.c" +/* See the note in itree_v1 in a comment that starts "NOTA BENE" for an + * explanation for why iomap.c is included here. + */ +#include "iomap.c" =20 int V2_minix_get_block(struct inode * inode, long block, struct buffer_head *bh_result, int create) @@ -69,7 +73,18 @@ void V2_minix_truncate(struct inode * inode) truncate(inode); } =20 -unsigned V2_minix_blocks(loff_t size, struct super_block *sb) +unsigned int V2_minix_blocks(loff_t size, struct super_block *sb) { return nblocks(size, sb); } + +int V2_minix_iomap_begin(struct inode *inode, loff_t offset, loff_t length, + unsigned int flags, struct iomap *iomap, struct iomap *srcmap) +{ + return minix_iomap_begin(inode, offset, length, flags, iomap, srcmap); +} + +const struct iomap_ops V2_minix_iomap_ops =3D { + .iomap_begin =3D V2_minix_iomap_begin, + .iomap_end =3D minix_iomap_end, +}; diff --git a/fs/minix/minix.h b/fs/minix/minix.h index 9e52d4302f0d..cf85edfb5bfa 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h @@ -5,6 +5,7 @@ #include #include #include +#include =20 #define INODE_VERSION(inode) minix_sb(inode->i_sb)->s_version #define MINIX_V1 0x0001 /* original minix fs */ @@ -77,13 +78,24 @@ int minix_make_empty(struct inode*, struct inode*); int minix_empty_dir(struct inode*); int minix_set_link(struct minix_dir_entry *de, struct folio *folio, struct inode *inode); + struct minix_dir_entry *minix_dotdot(struct inode*, struct folio **); ino_t minix_inode_by_name(struct dentry*); =20 +extern int V1_minix_iomap_begin(struct inode *inode, loff_t offset, + loff_t length, unsigned int flags, struct iomap *iomap, + struct iomap *srcmap); +extern int V2_minix_iomap_begin(struct inode *inode, loff_t offset, + loff_t length, unsigned int flags, struct iomap *iomap, + struct iomap *srcmap); + +extern const struct address_space_operations minix_aops; extern const struct inode_operations minix_file_inode_operations; extern const struct inode_operations minix_dir_inode_operations; extern const struct file_operations minix_file_operations; extern const struct file_operations minix_dir_operations; +extern const struct iomap_ops V1_minix_iomap_ops; +extern const struct iomap_ops V2_minix_iomap_ops; =20 static inline struct minix_sb_info *minix_sb(struct super_block *sb) { @@ -95,11 +107,17 @@ static inline struct minix_inode_info *minix_i(struct = inode *inode) return container_of(inode, struct minix_inode_info, vfs_inode); } =20 -static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksi= ze) +static inline unsigned int minix_blocks_needed(unsigned int bits, unsigned= int blocksize) { return DIV_ROUND_UP_POW2(bits, blocksize * 8); } =20 +static inline const struct iomap_ops *minix_iomap_ops_ver(struct inode *in= ode) +{ + return (INODE_VERSION(inode) =3D=3D MINIX_V1) ? + &V1_minix_iomap_ops : &V2_minix_iomap_ops; +} + #if defined(CONFIG_MINIX_FS_NATIVE_ENDIAN) && \ defined(CONFIG_MINIX_FS_BIG_ENDIAN_16BIT_INDEXED) =20 @@ -129,7 +147,7 @@ static inline unsigned minix_blocks_needed(unsigned bit= s, unsigned blocksize) * big-endian 16bit indexed bitmaps */ =20 -static inline int minix_find_first_zero_bit(const void *vaddr, unsigned si= ze) +static inline int minix_find_first_zero_bit(const void *vaddr, unsigned in= t size) { const unsigned short *p =3D vaddr, *addr =3D vaddr; unsigned short num; --=20 2.47.3 From nobody Sat Jul 25 23:03:35 2026 Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BB13312819 for ; Sat, 11 Jul 2026 20:59:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803573; cv=none; b=snMsDjpHY3Gv6cZeY57rdaDC9/cjijmak4Rw1NDo/aJunsn8g6vdo1ojjfdxTHk/l/ryHSSXbzFQqkxxAXQwarYtlqaY1NIF9paHZUJ+Hw06UsUVjuHPnZht5xiw6851a34BAeVf+53KhL/DizcP6UhiVSVF0w8VKXT5gZTk+Lg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803573; c=relaxed/simple; bh=MApZ9+VcV1CU1S6+9jaQdIXj3M5h5hU/HWXnTz4jg34=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E4SOkKyBgcgWQogugAfJwiyWMMq7juGs0sRoKD21zAHcKW0TXyAY/mTLK9EGd8H7398annYKRRlv+UblxjinIdVNo4bU1stSpA9eLMf4QqshuOG4GzBoTcvXaOPLlYh8rbH6cCGAF/DZP8IWGrAFaX1A/x0Z3uS2+FI97O6YUf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WgaqRhiA; arc=none smtp.client-ip=209.85.215.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WgaqRhiA" Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-c966b9ee9cbso955229a12.1 for ; Sat, 11 Jul 2026 13:59:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783803571; x=1784408371; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=7tB4aNIIl+6I/pIezbew7L22hRSnHScEtRtcn7y/r0w=; b=WgaqRhiAyl0lktGNB8DmqR0dUW51lWyuV1Lw+eQi0Db+Jkubixl1h/NaXuzgtlXHxX QSriUwuj5AmI0XFsFqAxPZZTzgBzs+KoJgqB18J5PiOOp6isEa/lb2wibEeqar44dwZs NL9/F2CKAyeQ63bbP3EWg5DZOCZY9alcRyFR4QyOjr15w+R55wUzt6eQCKZtj//rm2Gl h6b9BqdkEBiGB0VyXN7/iDkiH3NrWuTVzzKedzmWKzfe18IpEP6+URDiwHWqDvbPfZ2T c0+Tsaomtq2Qu7HPi+EoDTpsbDww3YW9fUFIyNkeBQqboLZ4WHnx5w8keQpBtxeSePnf iy8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783803571; x=1784408371; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=7tB4aNIIl+6I/pIezbew7L22hRSnHScEtRtcn7y/r0w=; b=kuY7NIyWJol0Kn3tW+1lqViybTAk6HVzDZc5by2imxchY9zox9a+YPFWWM0ocHYY5p Q8YXJtdEga+TT4485d9aN8Rb1gdm0olFw3cnB2wyrUYiUPfs1hDP1KEUEo1qAEoj3lzI q2BTkL16PpkDkzMEAv0DpqvCF+0EqohnIK6zlPbwHZ9z5nmrRgTMfqiK0tWSECKOJ/1q 5afKMLdiDN18fpD/UeLcs13jEum5f1xZLs0FaH4QK7iSX8g/QdqU5AIaKd7MbVQpEO73 XafcP7xM5ai4nDU/9+dx11tRrLWC2WS/rio1M/r6rKSX26H8FwGLUB9ZneCtCBcbt5mv NYeA== X-Gm-Message-State: AOJu0YyQEkHb6oXwO4UJgysfHWQPzD6Fy2uJexA9VXWUEeS7zQbgj3jg xF0ZcElf0myM5fy3+iLFHeXG+ZlbNJNVm+oVemVFsO1FneN79+aWsE9IQJ6DUQ== X-Gm-Gg: AfdE7cky1YLxBBu3p7TS9IP/KZDSmTqaJHe5W7f2l18jRIo4xMacfqtUyJ40aHNKaJ9 dR2V2CbHCQ7hmKUzLFDGQNeZS6lrngxZ2d6EqXQOFtdJbHKSmqwJfXWSOseKZrln9shDWSHoGg6 L8iG1Jk9QmEdmbzO28vsuMyhLaI+5h25+h87e+aaDTBXqvMmPaidtRhztxgD3BswEOOXuDXCMJI rBe1G4iPM4F2lNUfSN+RDWOj8iHaiGA9Okspfh+4Bao7z0rT7Pi4Jv+F+1FTudlciCZ/BmRXSCp ma0GZSaMkMRXGrC5q00LSKbb8LcPE7lP7UM0wwVlv5kIBl3bAdG1i+D2TXp+C1A4QTpLxo0ia8r 81cITMyw2VEwOFYCKCOOdUkCbAJnD0OSvgoMp4WdQ9v7gRR29v7mSfCneiaP0mCI= X-Received: by 2002:a05:6a00:21ca:b0:845:d286:1fb4 with SMTP id d2e1a72fcca58-8488975b2b8mr3537838b3a.50.1783803571413; Sat, 11 Jul 2026 13:59:31 -0700 (PDT) Received: from nineveh.sos.local ([131.191.24.68]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84880a44feasm2092057b3a.20.2026.07.11.13.59.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 13:59:30 -0700 (PDT) From: Jeremy Bingham To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, brauner@kernel.org, jkoolstra@xs4all.nl, jack@suse.cz, djwong@kernel.org, viro@zeniv.linux.org.uk, Jeremy Bingham Subject: [PATCH v3 4/5] minix: add file operation functions Date: Sat, 11 Jul 2026 13:59:08 -0700 Message-ID: <3f7e48122d2b280de63e7b901c7a1d7a99c0e063.1783707063.git.jbingham@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This adds the minix iomap file operation functions, including direct I/O functions, and updates the minix_file_operations struct to use them. Previously, most of the function pointers in minix_file_operations were the defaults. With the iomap changes, though, the defaults are no longer sufficient and minix-specific functions are required. The previously static minix_setattr function is also now exported; it will be used by minix_symlink_inode_operations. Signed-off-by: Jeremy Bingham --- fs/minix/file.c | 153 +++++++++++++++++++++++++++++++++++++++++++++-- fs/minix/minix.h | 2 + 2 files changed, 149 insertions(+), 6 deletions(-) diff --git a/fs/minix/file.c b/fs/minix/file.c index 86e5943cd2ff..88117c0e9f11 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -17,21 +17,162 @@ int minix_fsync(struct file *file, loff_t start, loff_= t end, int datasync) start, end, datasync); } =20 +static ssize_t minix_dio_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + struct inode *inode =3D iocb->ki_filp->f_mapping->host; + ssize_t ret; + + inode_lock_shared(inode); + + const struct iomap_ops *ops =3D minix_iomap_ops_ver(inode); + + ret =3D iomap_dio_rw(iocb, to, ops, NULL, 0, NULL, 0); + inode_unlock_shared(inode); + return ret; +} + +static int minix_dio_write_end_io(struct kiocb *iocb, ssize_t size, int er= ror, + unsigned int flags) +{ + struct inode *inode =3D file_inode(iocb->ki_filp); + loff_t pos =3D iocb->ki_pos; + + if (error) + return error; + + pos +=3D size; + if (size && pos > i_size_read(inode)) { + i_size_write(inode, pos); + mark_inode_dirty(inode); + } + return 0; +} + +static const struct iomap_dio_ops minix_dio_write_ops =3D { + .end_io =3D minix_dio_write_end_io, +}; + +static ssize_t minix_dio_write_iter(struct kiocb *iocb, struct iov_iter *f= rom) +{ + struct inode *inode =3D iocb->ki_filp->f_mapping->host; + ssize_t ret; + unsigned int flags =3D 0; + unsigned long blocksize =3D inode->i_sb->s_blocksize; + + inode_lock(inode); + ret =3D generic_write_checks(iocb, from); + if (ret <=3D 0) + goto out_unlock; + + ret =3D kiocb_modified(iocb); + if (ret) + goto out_unlock; + + if (iocb->ki_pos + iov_iter_count(from) > i_size_read(inode) || + !IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(from), blocksize)) + flags |=3D IOMAP_DIO_FORCE_WAIT; + + const struct iomap_ops *ops =3D minix_iomap_ops_ver(inode); + + ret =3D iomap_dio_rw(iocb, from, ops, + &minix_dio_write_ops, flags, NULL, 0); + if (ret =3D=3D -ENOTBLK) + ret =3D 0; /* fallback to buffered */ + + if (ret >=3D 0 && iov_iter_count(from)) { + loff_t pos; + loff_t endbyte; + ssize_t status; + + iocb->ki_flags &=3D ~IOCB_DIRECT; + iocb->ki_flags |=3D IOCB_DSYNC; + pos =3D iocb->ki_pos; + status =3D iomap_file_buffered_write(iocb, from, ops, + NULL, NULL); + if (unlikely(status < 0)) { + ret =3D status; + goto out_unlock; + } + + ret +=3D status; + endbyte =3D pos + status - 1; + invalidate_mapping_pages(inode->i_mapping, + pos >> PAGE_SHIFT, + endbyte >> PAGE_SHIFT); + if (ret > 0) + ret =3D generic_write_sync(iocb, ret); + } + +out_unlock: + inode_unlock(inode); + return ret; +} + +static ssize_t minix_file_read_iter(struct kiocb *iocb, struct iov_iter *t= o) +{ + if (iocb->ki_flags & IOCB_DIRECT) + return minix_dio_read_iter(iocb, to); + + return generic_file_read_iter(iocb, to); +} + +static ssize_t minix_file_write_iter(struct kiocb *iocb, struct iov_iter *= from) +{ + struct inode *inode =3D iocb->ki_filp->f_mapping->host; + ssize_t ret; + + /* minix_dio_write_iter also locks the inode and appears to do the same + * general sorts of checks as this, so just return directly from there. + */ + if (iocb->ki_flags & IOCB_DIRECT) + return minix_dio_write_iter(iocb, from); + + inode_lock(inode); + ret =3D generic_write_checks(iocb, from); + if (ret <=3D 0) + goto unlock; + + ret =3D file_modified(iocb->ki_filp); + if (ret) + goto unlock; + + const struct iomap_ops *ops =3D minix_iomap_ops_ver(inode); + + ret =3D iomap_file_buffered_write(iocb, from, ops, + NULL, NULL); + + if (ret > 0) + ret =3D generic_write_sync(iocb, ret); + +unlock: + inode_unlock(inode); + return ret; +} + +static int minix_file_open(struct inode *inode, struct file *filp) +{ + filp->f_mode |=3D FMODE_CAN_ODIRECT; + return generic_file_open(inode, filp); +} + /* - * We have mostly NULLs here: the current defaults are OK for - * the minix filesystem. + * We still have some NULLs here, but not as many of the current defaults = are + * still OK for the minix filesystem. */ + const struct file_operations minix_file_operations =3D { .llseek =3D generic_file_llseek, - .read_iter =3D generic_file_read_iter, - .write_iter =3D generic_file_write_iter, + .read_iter =3D minix_file_read_iter, + .write_iter =3D minix_file_write_iter, .mmap_prepare =3D generic_file_mmap_prepare, + .open =3D minix_file_open, .fsync =3D minix_fsync, .splice_read =3D filemap_splice_read, + .splice_write =3D iter_file_splice_write, }; =20 -static int minix_setattr(struct mnt_idmap *idmap, - struct dentry *dentry, struct iattr *attr) +int minix_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + struct iattr *attr) { struct inode *inode =3D d_inode(dentry); int error; diff --git a/fs/minix/minix.h b/fs/minix/minix.h index cf85edfb5bfa..45beadef0d8c 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h @@ -58,6 +58,8 @@ void minix_free_block(struct inode *inode, unsigned long = block); unsigned long minix_count_free_blocks(struct super_block *sb); int minix_getattr(struct mnt_idmap *, const struct path *, struct kstat *, u32, unsigned int); +int minix_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + struct iattr *attr); int minix_prepare_chunk(struct folio *folio, loff_t pos, unsigned len); struct mapping_metadata_bhs *minix_get_metadata_bhs(struct inode *inode); int minix_fsync(struct file *file, loff_t start, loff_t end, int datasync); --=20 2.47.3 From nobody Sat Jul 25 23:03:35 2026 Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72E982FD1DA for ; Sat, 11 Jul 2026 20:59:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803578; cv=none; b=BnziHP2wVbt/32fnB7CrVazPlW/1CMbtb8tUeIpJLfDZPDj0h9dkAdVTRxm2/uu5FU190MpbDGRKDmdAbcEuD2Nno5u3zepRxmFUvjsv4fsCEV7sYWN4yBSOWxqUsOoKB1Iikwabes7z5ZJXYsQMz69XxLgdM6puYdQI5VHhV4w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783803578; c=relaxed/simple; bh=S2c+amldauTM7YnNw3EfHUsePk7PpfRxalX3JOB2TqU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gToVvJkpQ0I0mqOS5triZNS5wK8fJC5zW/aF24RnK1r3N2XsdUh1bvRmRCJJ17lGeCZOr+/konZUYHlWty/9fB+bCsU+olR+bGIMQMx9TQg0OYTIinGaVLquxvrE+46zDHnm2/xkcuVVwPBoA8QwXZvB7hlFAkV3S2JUPXjrHRY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=W/TZhbi+; arc=none smtp.client-ip=209.85.210.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W/TZhbi+" Received: by mail-pf1-f172.google.com with SMTP id d2e1a72fcca58-8484a0b998fso3010476b3a.2 for ; Sat, 11 Jul 2026 13:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783803577; x=1784408377; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=xsTZk/W1iYG8o2QI+sZ33lAhlke6YlquVhNA6dVDEoU=; b=W/TZhbi+Lw2b17fWzRpJ5ALRNgpWRvHn/RSyptK9SLZdlZk8mnSRa1wSTkIS10d63g WJ9BzqOP2PImzj7C8K/FflZugZIEbtkQJ9t1BUy8HWVKvZdFJUu+qJwGb9gADtPVXwf1 jgJcwcJ7mAyZh4rGE5fHU2ExkkzxTi4aJB7yc4925bnTOeeWqsyp+kQifaWhNUiVmx8D mrT0oE2aQq2y7lauerqB+5WTs0ULaVrjxyLRzfSmroV77G9RmAnkXl3u7jPF7jk+vkQc tFs3XnEpINauAHf9IRV9eXmEc6LmkLthI0+QpbbY3rIVlPCC7lNvlI3B6LgoAb6j7Nmg ysRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783803577; x=1784408377; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=xsTZk/W1iYG8o2QI+sZ33lAhlke6YlquVhNA6dVDEoU=; b=DdZcY2afm7msYDcCF/kpvgrdYQsFkMwYt6KxBJhpaXsEzlDLCDurY+kiMB/TF6ZbdJ CDfdDZOMvwsThBY3DR8UmgrmCDOV7smayQ7Akw9lcKsr4ax5w76ie69Xxo0Ekplc17vm XKU7M6+rLqBYUNuDG1KjXMubZUjX+er70ZOvFGyneXD8oFQIwLt6klWMleT9sxHh55BR 72xze9urQ0y9XAkZQf+LsQ1rXw56GCl9rWVDsxLOj0A/QtfB3RguTVD1hLIJ/zq6ekRd mRhr16FGzpu+B3qd9bfdgrdqIW4Jcs9U3hSivKdohi6g+0IELt83tjnu4F2ded18iiU3 ZawQ== X-Gm-Message-State: AOJu0Yx2kUIno8OSF2KyOa1UOwTcm24XrrVP9J7x85VwrdkWj7FpxEH7 J8rm18Ma6nZHwUsM6y/yMHNyerxwIXmUWAamNTXRYUetTM+1T2QkupOk X-Gm-Gg: AfdE7cmB7CYqt4y3ISpfVBNvH68TRBPNy1aGvp5rsoaBoZBN6hpmTeLmHmfYMNyhp2N f5XQVl5rv0YjLxmsxUL5n9OGQGdI4XBsGWUXtc2h91eljBTdB7wsmw+myJYb6H0ixu1gNkQ8cJX AU3YtFYJancPkP4BFbA8vi7bPCWApj2Z/Sf/3zQidEjB01DXCCIw1G3Qa2/wyWhLlbhe0eeLeXj qeuUdFDjZeZQYdmnrjFAbGlfzY9WPbDaq+Q6w7h+vakLB492l2UkOpLMWSj0VtdSMrQLpM/rLOT 7v8TN8HFeE/QpRC+zDsyxwP5ZHb6r+hnha6G4jbgMo7dCCOo448ZIRpomGP8Sikik8wbRimo0uh IdFaS6kuV1QunVmyd98nMvkPOmZVcRhAg+JUrrMkoOhnzztskr+O132Z8zk1Wj53aSW1d5CHPrA == X-Received: by 2002:a05:6a00:1ca3:b0:848:2f77:e2de with SMTP id d2e1a72fcca58-848897aa4femr3468325b3a.71.1783803576746; Sat, 11 Jul 2026 13:59:36 -0700 (PDT) Received: from nineveh.sos.local ([131.191.24.68]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84880a44feasm2092057b3a.20.2026.07.11.13.59.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 13:59:36 -0700 (PDT) From: Jeremy Bingham To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, brauner@kernel.org, jkoolstra@xs4all.nl, jack@suse.cz, djwong@kernel.org, viro@zeniv.linux.org.uk, Jeremy Bingham Subject: [PATCH v3 5/5] minix: iomap inode operations Date: Sat, 11 Jul 2026 13:59:09 -0700 Message-ID: <5eaea9f680ed89adc933ed72391c3e762ca4ad9b.1783707063.git.jbingham@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Wire the new iomap functionality into the inode operations. Entirely new functions for writeback and a minix_writeback_ops struct have been added, and the address space operation functions have been updated to use iomap. Since directory operations still work the old way, the old functions have been preserved with new names. Directories also get their own address operation struct. Also, bmap support is dropped entirely per Darrick Wong's suggestion. This patch also updates minix_symlink to use the new iomap_symlink_write function, removing the need to bypass iomap to read and write symlinks directly. This was also suggested by Darrick Wong. Suggested-by: Darrick J. Wong Signed-off-by: Jeremy Bingham --- fs/minix/inode.c | 85 +++++++++++++++++++++++++++++++++++++++++------- fs/minix/namei.c | 8 ++++- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/fs/minix/inode.c b/fs/minix/inode.c index d5ba72f51049..f6747bacdb14 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -436,6 +436,31 @@ static int minix_statfs(struct dentry *dentry, struct = kstatfs *buf) return 0; } =20 +static ssize_t minix_writeback_range(struct iomap_writepage_ctx *wpc, + struct folio *folio, u64 pos, unsigned int len, u64 end_pos) +{ + int error; + + if (pos < wpc->iomap.offset || + pos >=3D wpc->iomap.offset + wpc->iomap.length) { + if (INODE_VERSION(wpc->inode) =3D=3D MINIX_V1) + error =3D V1_minix_iomap_begin(wpc->inode, pos, len, IOMAP_WRITE, + &wpc->iomap, NULL); + else + error =3D V2_minix_iomap_begin(wpc->inode, pos, len, IOMAP_WRITE, + &wpc->iomap, NULL); + if (error) + return error; + } + + return iomap_add_to_ioend(wpc, folio, pos, end_pos, len); +} + +static const struct iomap_writeback_ops minix_writeback_ops =3D { + .writeback_range =3D minix_writeback_range, + .writeback_submit =3D iomap_ioend_writeback_submit, +}; + static int minix_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { @@ -445,17 +470,45 @@ static int minix_get_block(struct inode *inode, secto= r_t block, return V2_minix_get_block(inode, block, bh_result, create); } =20 -static int minix_writepages(struct address_space *mapping, +/* The old minix_writepages, preserved for directory operations. */ +static int minix_block_writepages(struct address_space *mapping, struct writeback_control *wbc) { return mpage_writepages(mapping, wbc, minix_get_block); } =20 +static int minix_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + struct iomap_writepage_ctx wpc =3D { + .inode =3D mapping->host, + .wbc =3D wbc, + .ops =3D &minix_writeback_ops, + }; + return iomap_writepages(&wpc); +} + static int minix_read_folio(struct file *file, struct folio *folio) +{ + const struct iomap_ops *ops =3D minix_iomap_ops_ver(folio->mapping->host); + + iomap_bio_read_folio(folio, ops); + return 0; +} + +/* The old minix_read_folio, preserved for directory operations. */ +static int minix_block_read_folio(struct file *file, struct folio *folio) { return block_read_full_folio(folio, minix_get_block); } =20 +static void minix_readahead(struct readahead_control *rac) +{ + const struct iomap_ops *ops =3D minix_iomap_ops_ver(rac->mapping->host); + + iomap_bio_readahead(rac, ops); +} + int minix_prepare_chunk(struct folio *folio, loff_t pos, unsigned len) { return __block_write_begin(folio, pos, len, minix_get_block); @@ -485,26 +538,35 @@ static int minix_write_begin(const struct kiocb *iocb, return ret; } =20 -static sector_t minix_bmap(struct address_space *mapping, sector_t block) -{ - return generic_block_bmap(mapping,block,minix_get_block); -} - const struct address_space_operations minix_aops =3D { - .dirty_folio =3D block_dirty_folio, - .invalidate_folio =3D block_invalidate_folio, + .dirty_folio =3D iomap_dirty_folio, + .invalidate_folio =3D iomap_invalidate_folio, .read_folio =3D minix_read_folio, + .readahead =3D minix_readahead, .writepages =3D minix_writepages, + .migrate_folio =3D filemap_migrate_folio, + .is_partially_uptodate =3D iomap_is_partially_uptodate, + .release_folio =3D iomap_release_folio, + .error_remove_folio =3D generic_error_remove_folio, +}; + +/* A special aops for directories that keeps using the buffer head chunks,= at + * least for the time being. + */ +static const struct address_space_operations minix_dir_aops =3D { + .dirty_folio =3D block_dirty_folio, + .invalidate_folio =3D block_invalidate_folio, + .read_folio =3D minix_block_read_folio, .write_begin =3D minix_write_begin, .write_end =3D generic_write_end, .migrate_folio =3D buffer_migrate_folio, - .bmap =3D minix_bmap, - .direct_IO =3D noop_direct_IO + .writepages =3D minix_block_writepages, }; =20 static const struct inode_operations minix_symlink_inode_operations =3D { .get_link =3D page_get_link, .getattr =3D minix_getattr, + .setattr =3D minix_setattr, }; =20 void minix_set_inode(struct inode *inode, dev_t rdev) @@ -516,7 +578,7 @@ void minix_set_inode(struct inode *inode, dev_t rdev) } else if (S_ISDIR(inode->i_mode)) { inode->i_op =3D &minix_dir_inode_operations; inode->i_fop =3D &minix_dir_operations; - inode->i_mapping->a_ops =3D &minix_aops; + inode->i_mapping->a_ops =3D &minix_dir_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op =3D &minix_symlink_inode_operations; inode_nohighmem(inode); @@ -768,4 +830,3 @@ module_init(init_minix_fs) module_exit(exit_minix_fs) MODULE_DESCRIPTION("Minix file system"); MODULE_LICENSE("GPL"); - diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 263e4ba8b1c8..bb5892f9fb2a 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -6,6 +6,7 @@ */ =20 #include "minix.h" +#include =20 static int add_nondir(struct dentry *dentry, struct inode *inode) { @@ -84,12 +85,17 @@ static int minix_symlink(struct mnt_idmap *idmap, struc= t inode *dir, return PTR_ERR(inode); =20 minix_set_inode(inode, 0); - err =3D page_symlink(inode, symname, i); + err =3D iomap_symlink_write(inode, symname, i, minix_iomap_ops_ver(inode)= , NULL, NULL); + + if (!err) + i_size_write(inode, i - 1); + if (unlikely(err)) { inode_dec_link_count(inode); iput(inode); return err; } + return add_nondir(dentry, inode); } =20 --=20 2.47.3