Skip to content

Commit 53d514b

Browse files
ToolmanPhsiangkao
authored andcommitted
erofs: refactor read_inode calling convention
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 <[email protected]> Link: https://lore.kernel.org/all/20240425222847.GN2118490@ZenIV/ Signed-off-by: Yiyang Wu <[email protected]> Reviewed-by: Gao Xiang <[email protected]> Reviewed-by: Chao Yu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Gao Xiang <[email protected]>
1 parent b1bbb9a commit 53d514b

File tree

1 file changed

+52
-59
lines changed

1 file changed

+52
-59
lines changed

fs/erofs/inode.c

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,24 @@
88

99
#include <trace/events/erofs.h>
1010

11-
static void *erofs_read_inode(struct erofs_buf *buf,
12-
struct inode *inode, unsigned int *ofs)
11+
static int erofs_fill_symlink(struct inode *inode, void *kaddr,
12+
unsigned int m_pofs)
13+
{
14+
struct erofs_inode *vi = EROFS_I(inode);
15+
loff_t off;
16+
17+
m_pofs += vi->xattr_isize;
18+
/* check if it cannot be handled with fast symlink scheme */
19+
if (vi->datalayout != EROFS_INODE_FLAT_INLINE || inode->i_size < 0 ||
20+
check_add_overflow(m_pofs, inode->i_size, &off) ||
21+
off > i_blocksize(inode))
22+
return 0;
23+
24+
inode->i_link = kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL);
25+
return inode->i_link ? 0 : -ENOMEM;
26+
}
27+
28+
static int erofs_read_inode(struct inode *inode)
1329
{
1430
struct super_block *sb = inode->i_sb;
1531
struct erofs_sb_info *sbi = EROFS_SB(sb);
@@ -20,20 +36,21 @@ static void *erofs_read_inode(struct erofs_buf *buf,
2036
struct erofs_inode_compact *dic;
2137
struct erofs_inode_extended *die, *copied = NULL;
2238
union erofs_inode_i_u iu;
23-
unsigned int ifmt;
24-
int err;
39+
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
40+
unsigned int ifmt, ofs;
41+
int err = 0;
2542

2643
blkaddr = erofs_blknr(sb, inode_loc);
27-
*ofs = erofs_blkoff(sb, inode_loc);
44+
ofs = erofs_blkoff(sb, inode_loc);
2845

29-
kaddr = erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr), EROFS_KMAP);
46+
kaddr = erofs_read_metabuf(&buf, sb, erofs_pos(sb, blkaddr), EROFS_KMAP);
3047
if (IS_ERR(kaddr)) {
3148
erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld",
3249
vi->nid, PTR_ERR(kaddr));
33-
return kaddr;
50+
return PTR_ERR(kaddr);
3451
}
3552

36-
dic = kaddr + *ofs;
53+
dic = kaddr + ofs;
3754
ifmt = le16_to_cpu(dic->i_format);
3855
if (ifmt & ~EROFS_I_ALL) {
3956
erofs_err(sb, "unsupported i_format %u of nid %llu",
@@ -54,28 +71,28 @@ static void *erofs_read_inode(struct erofs_buf *buf,
5471
case EROFS_INODE_LAYOUT_EXTENDED:
5572
vi->inode_isize = sizeof(struct erofs_inode_extended);
5673
/* check if the extended inode acrosses block boundary */
57-
if (*ofs + vi->inode_isize <= sb->s_blocksize) {
58-
*ofs += vi->inode_isize;
74+
if (ofs + vi->inode_isize <= sb->s_blocksize) {
75+
ofs += vi->inode_isize;
5976
die = (struct erofs_inode_extended *)dic;
6077
} else {
61-
const unsigned int gotten = sb->s_blocksize - *ofs;
78+
const unsigned int gotten = sb->s_blocksize - ofs;
6279

6380
copied = kmalloc(vi->inode_isize, GFP_KERNEL);
6481
if (!copied) {
6582
err = -ENOMEM;
6683
goto err_out;
6784
}
6885
memcpy(copied, dic, gotten);
69-
kaddr = erofs_read_metabuf(buf, sb, erofs_pos(sb, blkaddr + 1),
86+
kaddr = erofs_read_metabuf(&buf, sb, erofs_pos(sb, blkaddr + 1),
7087
EROFS_KMAP);
7188
if (IS_ERR(kaddr)) {
7289
erofs_err(sb, "failed to get inode payload block (nid: %llu), err %ld",
7390
vi->nid, PTR_ERR(kaddr));
7491
kfree(copied);
75-
return kaddr;
92+
return PTR_ERR(kaddr);
7693
}
77-
*ofs = vi->inode_isize - gotten;
78-
memcpy((u8 *)copied + gotten, kaddr, *ofs);
94+
ofs = vi->inode_isize - gotten;
95+
memcpy((u8 *)copied + gotten, kaddr, ofs);
7996
die = copied;
8097
}
8198
vi->xattr_isize = erofs_xattr_ibody_size(die->i_xattr_icount);
@@ -91,11 +108,10 @@ static void *erofs_read_inode(struct erofs_buf *buf,
91108

92109
inode->i_size = le64_to_cpu(die->i_size);
93110
kfree(copied);
94-
copied = NULL;
95111
break;
96112
case EROFS_INODE_LAYOUT_COMPACT:
97113
vi->inode_isize = sizeof(struct erofs_inode_compact);
98-
*ofs += vi->inode_isize;
114+
ofs += vi->inode_isize;
99115
vi->xattr_isize = erofs_xattr_ibody_size(dic->i_xattr_icount);
100116

101117
inode->i_mode = le16_to_cpu(dic->i_mode);
@@ -120,6 +136,11 @@ static void *erofs_read_inode(struct erofs_buf *buf,
120136
case S_IFDIR:
121137
case S_IFLNK:
122138
vi->raw_blkaddr = le32_to_cpu(iu.raw_blkaddr);
139+
if(S_ISLNK(inode->i_mode)) {
140+
err = erofs_fill_symlink(inode, kaddr, ofs);
141+
if (err)
142+
goto err_out;
143+
}
123144
break;
124145
case S_IFCHR:
125146
case S_IFBLK:
@@ -165,51 +186,24 @@ static void *erofs_read_inode(struct erofs_buf *buf,
165186
inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9;
166187
else
167188
inode->i_blocks = nblks << (sb->s_blocksize_bits - 9);
168-
return kaddr;
169189

170190
err_out:
171-
DBG_BUGON(1);
172-
kfree(copied);
173-
erofs_put_metabuf(buf);
174-
return ERR_PTR(err);
175-
}
176-
177-
static int erofs_fill_symlink(struct inode *inode, void *kaddr,
178-
unsigned int m_pofs)
179-
{
180-
struct erofs_inode *vi = EROFS_I(inode);
181-
loff_t off;
182-
183-
m_pofs += vi->xattr_isize;
184-
/* check if it cannot be handled with fast symlink scheme */
185-
if (vi->datalayout != EROFS_INODE_FLAT_INLINE || inode->i_size < 0 ||
186-
check_add_overflow(m_pofs, inode->i_size, &off) ||
187-
off > i_blocksize(inode)) {
188-
inode->i_op = &erofs_symlink_iops;
189-
return 0;
190-
}
191-
192-
inode->i_link = kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL);
193-
if (!inode->i_link)
194-
return -ENOMEM;
195-
inode->i_op = &erofs_fast_symlink_iops;
196-
return 0;
191+
DBG_BUGON(err);
192+
erofs_put_metabuf(&buf);
193+
return err;
197194
}
198195

199196
static int erofs_fill_inode(struct inode *inode)
200197
{
201198
struct erofs_inode *vi = EROFS_I(inode);
202-
struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
203-
void *kaddr;
204-
unsigned int ofs;
205-
int err = 0;
199+
int err;
206200

207201
trace_erofs_fill_inode(inode);
208202

209203
/* read inode base data from disk */
210-
kaddr = erofs_read_inode(&buf, inode, &ofs);
211-
if (IS_ERR(kaddr))
212-
return PTR_ERR(kaddr);
204+
err = erofs_read_inode(inode);
205+
if (err)
206+
return err;
213207

214208
/* setup the new inode */
215209
switch (inode->i_mode & S_IFMT) {
@@ -226,9 +220,10 @@ static int erofs_fill_inode(struct inode *inode)
226220
inode_nohighmem(inode);
227221
break;
228222
case S_IFLNK:
229-
err = erofs_fill_symlink(inode, kaddr, ofs);
230-
if (err)
231-
goto out_unlock;
223+
if (inode->i_link)
224+
inode->i_op = &erofs_fast_symlink_iops;
225+
else
226+
inode->i_op = &erofs_symlink_iops;
232227
inode_nohighmem(inode);
233228
break;
234229
case S_IFCHR:
@@ -237,10 +232,9 @@ static int erofs_fill_inode(struct inode *inode)
237232
case S_IFSOCK:
238233
inode->i_op = &erofs_generic_iops;
239234
init_special_inode(inode, inode->i_mode, inode->i_rdev);
240-
goto out_unlock;
235+
return 0;
241236
default:
242-
err = -EFSCORRUPTED;
243-
goto out_unlock;
237+
return -EFSCORRUPTED;
244238
}
245239

246240
mapping_set_large_folios(inode->i_mapping);
@@ -264,8 +258,7 @@ static int erofs_fill_inode(struct inode *inode)
264258
inode->i_mapping->a_ops = &erofs_fileio_aops;
265259
#endif
266260
}
267-
out_unlock:
268-
erofs_put_metabuf(&buf);
261+
269262
return err;
270263
}
271264

0 commit comments

Comments
 (0)