From nobody Fri Dec 19 10:43:34 2025 Received: from mail.tlmp.cc (unknown [148.135.17.20]) (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 71F2715B155 for ; Mon, 2 Sep 2024 07:01:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.135.17.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725260464; cv=none; b=ekm9eRpLZROmcNjVPm87t1A/XKKxozw9yWkD1wobxrdXsVcN/k4HT/0T5M9dOA5lwIeRfSpTs5oy3GCJ6txd/UaxTLbWsrkRxmdl3CW85eBT3lvHTkeBt6PzLZbP1jEKv+gHqyFRHUFIpeqrshLLqHWPjap2ViLdUNagD60MIoI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725260464; c=relaxed/simple; bh=uZAZBJaYfqYWH5VJenRwGn/sZoeyTrErt6D/bwEfKN0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tTE+1It5cYWmSj3fZ+qLW0KE3YqD33uhwxuFu0RqCM+NLKGo8jkb8spV0qrhMflHkI71YOi/uPiJw/WLeZQzCxz7UXQuspGtwTd6c+8YKg4XciKx9KbqQAtFMUohH5U0M7hiqF0y7U8EL3qIOUpL6yd5WnfSCPCz1n2wkUZU3Sc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=tlmp.cc; spf=pass smtp.mailfrom=tlmp.cc; dkim=pass (2048-bit key) header.d=tlmp.cc header.i=@tlmp.cc header.b=U4t5KH8j; arc=none smtp.client-ip=148.135.17.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=tlmp.cc Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=tlmp.cc Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=tlmp.cc header.i=@tlmp.cc header.b="U4t5KH8j" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 58CA869838; Mon, 2 Sep 2024 03:01:00 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tlmp.cc; s=dkim; t=1725260461; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Zk2uR11QphT7oi+0jYgUeJopixxchpFds3CpBMapZy8=; b=U4t5KH8jOiSHBhljBfudXpU+JAGWf4k5IdiP7/a7fWL2euKtLEApGOk13IAFrR6/4N4U5k 8imojhzyz+JBHdC/8ZFpqL90Is90/EgyG905LZuFAzBDWXzk5G8OIksa/kww2OLZSLtuIn ioMCQ9nPC2S3c00N+xZgChQPZdXY33Xon5WPGAM70ny1152E3a4zSvKv7SdaUkBadoSiEx ggMche5mO7EBrcZ0dUoHmtzzyWoBhz8HbOxssOVBcAIaezsIKjKarsvGU0ji36WsgEGne0 hrKJDjLyk8SAxUSWOW04P04CtrxPiZqN+wUW2yn0Rt7Ft1HQ2Yo/rDhggPFTsg== From: Yiyang Wu To: hsiangkao@linux.alibaba.com Cc: linux-erofs@lists.ozlabs.org, linux-kernel@vger.kernel.org, Yiyang Wu , Al Viro Subject: [PATCH V2 2/2] erofs: refactor read_inode calling convention Date: Mon, 2 Sep 2024 15:00:47 +0800 Message-ID: <20240902070047.384952-3-toolmanp@tlmp.cc> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240902070047.384952-1-toolmanp@tlmp.cc> References: <20240902070047.384952-1-toolmanp@tlmp.cc> 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 X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Refactor out the iop binding behavior out of the erofs_fill_symlink and move erofs_buf into the erofs_read_inode, so that erofs_fill_inode can only deal with inode operation bindings and can be decoupled from metabuf operations. This results in better calling conventions. Note that after this patch, we do not need erofs_buf and ofs as parameters any more when calling erofs_read_inode as all the data operations are now included in itself. Suggested-by: Al Viro Link: https://lore.kernel.org/all/20240425222847.GN2118490@ZenIV/ Signed-off-by: Yiyang Wu --- fs/erofs/inode.c | 126 ++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index d051afe39670..d854509bb082 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -8,8 +8,39 @@ =20 #include =20 -static void *erofs_read_inode(struct erofs_buf *buf, - struct inode *inode, unsigned int *ofs) +static int erofs_fill_symlink(struct inode *inode, void *kaddr, + unsigned int m_pofs) +{ + struct erofs_inode *vi =3D EROFS_I(inode); + unsigned int bsz =3D i_blocksize(inode); + char *lnk; + + /* if it cannot be handled with fast symlink scheme */ + if (vi->datalayout !=3D EROFS_INODE_FLAT_INLINE || + inode->i_size >=3D bsz || inode->i_size < 0) { + return 0; + } + + m_pofs +=3D vi->xattr_isize; + /* inline symlink data shouldn't cross block boundary */ + if (m_pofs + inode->i_size > bsz) { + erofs_err(inode->i_sb, + "inline data cross block boundary @ nid %llu", + vi->nid); + DBG_BUGON(1); + return -EFSCORRUPTED; + } + + lnk =3D kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL); + + if (!lnk) + return -ENOMEM; + + inode->i_link =3D lnk; + return 0; +} + +static int erofs_read_inode(struct inode *inode) { struct super_block *sb =3D inode->i_sb; struct erofs_sb_info *sbi =3D EROFS_SB(sb); @@ -20,20 +51,21 @@ static void *erofs_read_inode(struct erofs_buf *buf, struct erofs_inode_compact *dic; struct erofs_inode_extended *die, *copied =3D NULL; union erofs_inode_i_u iu; - unsigned int ifmt; + struct erofs_buf buf; + unsigned int ifmt, ofs; int err; =20 blkaddr =3D erofs_blknr(sb, inode_loc); - *ofs =3D erofs_blkoff(sb, inode_loc); + ofs =3D erofs_blkoff(sb, inode_loc); =20 - kaddr =3D erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr), EROFS_KMAP); + kaddr =3D erofs_read_metabuf(&buf, sb, erofs_pos(sb, blkaddr), EROFS_KMAP= ); if (IS_ERR(kaddr)) { erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld", vi->nid, PTR_ERR(kaddr)); - return kaddr; + return PTR_ERR(kaddr); } =20 - dic =3D kaddr + *ofs; + dic =3D kaddr + ofs; ifmt =3D le16_to_cpu(dic->i_format); if (ifmt & ~EROFS_I_ALL) { erofs_err(sb, "unsupported i_format %u of nid %llu", @@ -54,11 +86,11 @@ static void *erofs_read_inode(struct erofs_buf *buf, case EROFS_INODE_LAYOUT_EXTENDED: vi->inode_isize =3D sizeof(struct erofs_inode_extended); /* check if the extended inode acrosses block boundary */ - if (*ofs + vi->inode_isize <=3D sb->s_blocksize) { - *ofs +=3D vi->inode_isize; + if (ofs + vi->inode_isize <=3D sb->s_blocksize) { + ofs +=3D vi->inode_isize; die =3D (struct erofs_inode_extended *)dic; } else { - const unsigned int gotten =3D sb->s_blocksize - *ofs; + const unsigned int gotten =3D sb->s_blocksize - ofs; =20 copied =3D kmalloc(vi->inode_isize, GFP_KERNEL); if (!copied) { @@ -66,16 +98,16 @@ static void *erofs_read_inode(struct erofs_buf *buf, goto err_out; } memcpy(copied, dic, gotten); - kaddr =3D erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr + 1), + kaddr =3D erofs_read_metabuf(&buf, sb, erofs_pos(sb, blkaddr + 1), EROFS_KMAP); if (IS_ERR(kaddr)) { erofs_err(sb, "failed to get inode payload block (nid: %llu), err %ld", vi->nid, PTR_ERR(kaddr)); kfree(copied); - return kaddr; + return PTR_ERR(kaddr); } - *ofs =3D vi->inode_isize - gotten; - memcpy((u8 *)copied + gotten, kaddr, *ofs); + ofs =3D vi->inode_isize - gotten; + memcpy((u8 *)copied + gotten, kaddr, ofs); die =3D copied; } vi->xattr_isize =3D erofs_xattr_ibody_size(die->i_xattr_icount); @@ -95,7 +127,7 @@ static void *erofs_read_inode(struct erofs_buf *buf, break; case EROFS_INODE_LAYOUT_COMPACT: vi->inode_isize =3D sizeof(struct erofs_inode_compact); - *ofs +=3D vi->inode_isize; + ofs +=3D vi->inode_isize; vi->xattr_isize =3D erofs_xattr_ibody_size(dic->i_xattr_icount); =20 inode->i_mode =3D le16_to_cpu(dic->i_mode); @@ -119,6 +151,11 @@ static void *erofs_read_inode(struct erofs_buf *buf, case S_IFREG: case S_IFDIR: case S_IFLNK: + if(S_ISLNK(inode->i_mode)) { + err =3D erofs_fill_symlink(inode, kaddr, ofs); + if(err) + goto err_out; + } vi->raw_blkaddr =3D le32_to_cpu(iu.raw_blkaddr); break; case S_IFCHR: @@ -165,63 +202,29 @@ static void *erofs_read_inode(struct erofs_buf *buf, inode->i_blocks =3D round_up(inode->i_size, sb->s_blocksize) >> 9; else inode->i_blocks =3D nblks << (sb->s_blocksize_bits - 9); - return kaddr; + + erofs_put_metabuf(&buf); + return 0; =20 err_out: DBG_BUGON(1); kfree(copied); - erofs_put_metabuf(buf); - return ERR_PTR(err); + erofs_put_metabuf(&buf); + return err; } =20 -static int erofs_fill_symlink(struct inode *inode, void *kaddr, - unsigned int m_pofs) -{ - struct erofs_inode *vi =3D EROFS_I(inode); - unsigned int bsz =3D i_blocksize(inode); - char *lnk; - - /* if it cannot be handled with fast symlink scheme */ - if (vi->datalayout !=3D EROFS_INODE_FLAT_INLINE || - inode->i_size >=3D bsz || inode->i_size < 0) { - inode->i_op =3D &erofs_symlink_iops; - return 0; - } - - m_pofs +=3D vi->xattr_isize; - /* inline symlink data shouldn't cross block boundary */ - if (m_pofs + inode->i_size > bsz) { - erofs_err(inode->i_sb, - "inline data cross block boundary @ nid %llu", - vi->nid); - DBG_BUGON(1); - return -EFSCORRUPTED; - } - - lnk =3D kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL); - - if (!lnk) - return -ENOMEM; - - inode->i_link =3D lnk; - inode->i_op =3D &erofs_fast_symlink_iops; - return 0; -} =20 static int erofs_fill_inode(struct inode *inode) { struct erofs_inode *vi =3D EROFS_I(inode); - struct erofs_buf buf =3D __EROFS_BUF_INITIALIZER; - void *kaddr; - unsigned int ofs; int err =3D 0; =20 trace_erofs_fill_inode(inode); =20 /* read inode base data from disk */ - kaddr =3D erofs_read_inode(&buf, inode, &ofs); - if (IS_ERR(kaddr)) - return PTR_ERR(kaddr); + err =3D erofs_read_inode(inode); + if (err) + goto out_unlock; =20 /* setup the new inode */ switch (inode->i_mode & S_IFMT) { @@ -238,9 +241,11 @@ static int erofs_fill_inode(struct inode *inode) inode_nohighmem(inode); break; case S_IFLNK: - err =3D erofs_fill_symlink(inode, kaddr, ofs); - if (err) - goto out_unlock; + if (inode->i_link) + inode->i_op =3D &erofs_fast_symlink_iops; + else + inode->i_op =3D &erofs_symlink_iops; + inode_nohighmem(inode); break; case S_IFCHR: @@ -273,7 +278,6 @@ static int erofs_fill_inode(struct inode *inode) #endif } out_unlock: - erofs_put_metabuf(&buf); return err; } =20 --=20 2.46.0