Skip to content

Commit ed90ed5

Browse files
committed
Merge tag 'erofs-for-6.13-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull erofs fixes from Gao Xiang: "The first one fixes a syzbot UAF report caused by a commit introduced in this cycle, but it also addresses a longstanding memory leak. The second one resolves a PSI memstall mis-accounting issue. The remaining patches switch file-backed mounts to use buffered I/Os by default instead of direct I/Os, since the page cache of underlay files is typically valid and maybe even dirty. This change also aligns with the default policy of loopback devices. A mount option has been added to try to use direct I/Os explicitly. Summary: - Fix (pcluster) memory leak and (sbi) UAF after umounting - Fix a case of PSI memstall mis-accounting - Use buffered I/Os by default for file-backed mounts" * tag 'erofs-for-6.13-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: use buffered I/O for file-backed mounts by default erofs: reference `struct erofs_device_info` for erofs_map_dev erofs: use `struct erofs_device_info` for the primary device erofs: add erofs_sb_free() helper MAINTAINERS: erofs: update Yue Hu's email address erofs: fix PSI memstall accounting erofs: fix rare pcluster memory leak after unmounting
2 parents 1f13c38 + 6422cde commit ed90ed5

File tree

8 files changed

+79
-82
lines changed

8 files changed

+79
-82
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8453,7 +8453,7 @@ F: include/video/s1d13xxxfb.h
84538453
EROFS FILE SYSTEM
84548454
M: Gao Xiang <[email protected]>
84558455
M: Chao Yu <[email protected]>
8456-
R: Yue Hu <huyue2@coolpad.com>
8456+
R: Yue Hu <zbestahu@gmail.com>
84578457
R: Jeffle Xu <[email protected]>
84588458
R: Sandeep Dhavale <[email protected]>
84598459

fs/erofs/data.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
5656

5757
buf->file = NULL;
5858
if (erofs_is_fileio_mode(sbi)) {
59-
buf->file = sbi->fdev; /* some fs like FUSE needs it */
59+
buf->file = sbi->dif0.file; /* some fs like FUSE needs it */
6060
buf->mapping = buf->file->f_mapping;
6161
} else if (erofs_is_fscache_mode(sb))
62-
buf->mapping = sbi->s_fscache->inode->i_mapping;
62+
buf->mapping = sbi->dif0.fscache->inode->i_mapping;
6363
else
6464
buf->mapping = sb->s_bdev->bd_mapping;
6565
}
@@ -179,19 +179,13 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
179179
}
180180

181181
static void erofs_fill_from_devinfo(struct erofs_map_dev *map,
182-
struct erofs_device_info *dif)
182+
struct super_block *sb, struct erofs_device_info *dif)
183183
{
184+
map->m_sb = sb;
185+
map->m_dif = dif;
184186
map->m_bdev = NULL;
185-
map->m_fp = NULL;
186-
if (dif->file) {
187-
if (S_ISBLK(file_inode(dif->file)->i_mode))
188-
map->m_bdev = file_bdev(dif->file);
189-
else
190-
map->m_fp = dif->file;
191-
}
192-
map->m_daxdev = dif->dax_dev;
193-
map->m_dax_part_off = dif->dax_part_off;
194-
map->m_fscache = dif->fscache;
187+
if (dif->file && S_ISBLK(file_inode(dif->file)->i_mode))
188+
map->m_bdev = file_bdev(dif->file);
195189
}
196190

197191
int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
@@ -201,12 +195,8 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
201195
erofs_off_t startoff, length;
202196
int id;
203197

204-
map->m_bdev = sb->s_bdev;
205-
map->m_daxdev = EROFS_SB(sb)->dax_dev;
206-
map->m_dax_part_off = EROFS_SB(sb)->dax_part_off;
207-
map->m_fscache = EROFS_SB(sb)->s_fscache;
208-
map->m_fp = EROFS_SB(sb)->fdev;
209-
198+
erofs_fill_from_devinfo(map, sb, &EROFS_SB(sb)->dif0);
199+
map->m_bdev = sb->s_bdev; /* use s_bdev for the primary device */
210200
if (map->m_deviceid) {
211201
down_read(&devs->rwsem);
212202
dif = idr_find(&devs->tree, map->m_deviceid - 1);
@@ -219,7 +209,7 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
219209
up_read(&devs->rwsem);
220210
return 0;
221211
}
222-
erofs_fill_from_devinfo(map, dif);
212+
erofs_fill_from_devinfo(map, sb, dif);
223213
up_read(&devs->rwsem);
224214
} else if (devs->extra_devices && !devs->flatdev) {
225215
down_read(&devs->rwsem);
@@ -232,7 +222,7 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
232222
if (map->m_pa >= startoff &&
233223
map->m_pa < startoff + length) {
234224
map->m_pa -= startoff;
235-
erofs_fill_from_devinfo(map, dif);
225+
erofs_fill_from_devinfo(map, sb, dif);
236226
break;
237227
}
238228
}
@@ -302,7 +292,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
302292

303293
iomap->offset = map.m_la;
304294
if (flags & IOMAP_DAX)
305-
iomap->dax_dev = mdev.m_daxdev;
295+
iomap->dax_dev = mdev.m_dif->dax_dev;
306296
else
307297
iomap->bdev = mdev.m_bdev;
308298
iomap->length = map.m_llen;
@@ -331,7 +321,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
331321
iomap->type = IOMAP_MAPPED;
332322
iomap->addr = mdev.m_pa;
333323
if (flags & IOMAP_DAX)
334-
iomap->addr += mdev.m_dax_part_off;
324+
iomap->addr += mdev.m_dif->dax_part_off;
335325
}
336326
return 0;
337327
}

fs/erofs/fileio.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct erofs_fileio_rq {
99
struct bio_vec bvecs[BIO_MAX_VECS];
1010
struct bio bio;
1111
struct kiocb iocb;
12+
struct super_block *sb;
1213
};
1314

1415
struct erofs_fileio {
@@ -52,8 +53,9 @@ static void erofs_fileio_rq_submit(struct erofs_fileio_rq *rq)
5253
rq->iocb.ki_pos = rq->bio.bi_iter.bi_sector << SECTOR_SHIFT;
5354
rq->iocb.ki_ioprio = get_current_ioprio();
5455
rq->iocb.ki_complete = erofs_fileio_ki_complete;
55-
rq->iocb.ki_flags = (rq->iocb.ki_filp->f_mode & FMODE_CAN_ODIRECT) ?
56-
IOCB_DIRECT : 0;
56+
if (test_opt(&EROFS_SB(rq->sb)->opt, DIRECT_IO) &&
57+
rq->iocb.ki_filp->f_mode & FMODE_CAN_ODIRECT)
58+
rq->iocb.ki_flags = IOCB_DIRECT;
5759
iov_iter_bvec(&iter, ITER_DEST, rq->bvecs, rq->bio.bi_vcnt,
5860
rq->bio.bi_iter.bi_size);
5961
ret = vfs_iocb_iter_read(rq->iocb.ki_filp, &rq->iocb, &iter);
@@ -67,7 +69,8 @@ static struct erofs_fileio_rq *erofs_fileio_rq_alloc(struct erofs_map_dev *mdev)
6769
GFP_KERNEL | __GFP_NOFAIL);
6870

6971
bio_init(&rq->bio, NULL, rq->bvecs, BIO_MAX_VECS, REQ_OP_READ);
70-
rq->iocb.ki_filp = mdev->m_fp;
72+
rq->iocb.ki_filp = mdev->m_dif->file;
73+
rq->sb = mdev->m_sb;
7174
return rq;
7275
}
7376

fs/erofs/fscache.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ struct bio *erofs_fscache_bio_alloc(struct erofs_map_dev *mdev)
198198

199199
io = kmalloc(sizeof(*io), GFP_KERNEL | __GFP_NOFAIL);
200200
bio_init(&io->bio, NULL, io->bvecs, BIO_MAX_VECS, REQ_OP_READ);
201-
io->io.private = mdev->m_fscache->cookie;
201+
io->io.private = mdev->m_dif->fscache->cookie;
202202
io->io.end_io = erofs_fscache_bio_endio;
203203
refcount_set(&io->io.ref, 1);
204204
return &io->bio;
@@ -316,7 +316,7 @@ static int erofs_fscache_data_read_slice(struct erofs_fscache_rq *req)
316316
if (!io)
317317
return -ENOMEM;
318318
iov_iter_xarray(&io->iter, ITER_DEST, &mapping->i_pages, pos, count);
319-
ret = erofs_fscache_read_io_async(mdev.m_fscache->cookie,
319+
ret = erofs_fscache_read_io_async(mdev.m_dif->fscache->cookie,
320320
mdev.m_pa + (pos - map.m_la), io);
321321
erofs_fscache_req_io_put(io);
322322

@@ -657,22 +657,22 @@ int erofs_fscache_register_fs(struct super_block *sb)
657657
if (IS_ERR(fscache))
658658
return PTR_ERR(fscache);
659659

660-
sbi->s_fscache = fscache;
660+
sbi->dif0.fscache = fscache;
661661
return 0;
662662
}
663663

664664
void erofs_fscache_unregister_fs(struct super_block *sb)
665665
{
666666
struct erofs_sb_info *sbi = EROFS_SB(sb);
667667

668-
erofs_fscache_unregister_cookie(sbi->s_fscache);
668+
erofs_fscache_unregister_cookie(sbi->dif0.fscache);
669669

670670
if (sbi->domain)
671671
erofs_fscache_domain_put(sbi->domain);
672672
else
673673
fscache_relinquish_volume(sbi->volume, NULL, false);
674674

675-
sbi->s_fscache = NULL;
675+
sbi->dif0.fscache = NULL;
676676
sbi->volume = NULL;
677677
sbi->domain = NULL;
678678
}

fs/erofs/internal.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ struct erofs_xattr_prefix_item {
107107
};
108108

109109
struct erofs_sb_info {
110+
struct erofs_device_info dif0;
110111
struct erofs_mount_opts opt; /* options */
111112
#ifdef CONFIG_EROFS_FS_ZIP
112113
/* list for all registered superblocks, mainly for shrinker */
@@ -124,13 +125,9 @@ struct erofs_sb_info {
124125

125126
struct erofs_sb_lz4_info lz4;
126127
#endif /* CONFIG_EROFS_FS_ZIP */
127-
struct file *fdev;
128128
struct inode *packed_inode;
129129
struct erofs_dev_context *devs;
130-
struct dax_device *dax_dev;
131-
u64 dax_part_off;
132130
u64 total_blocks;
133-
u32 primarydevice_blocks;
134131

135132
u32 meta_blkaddr;
136133
#ifdef CONFIG_EROFS_FS_XATTR
@@ -166,7 +163,6 @@ struct erofs_sb_info {
166163

167164
/* fscache support */
168165
struct fscache_volume *volume;
169-
struct erofs_fscache *s_fscache;
170166
struct erofs_domain *domain;
171167
char *fsid;
172168
char *domain_id;
@@ -180,14 +176,15 @@ struct erofs_sb_info {
180176
#define EROFS_MOUNT_POSIX_ACL 0x00000020
181177
#define EROFS_MOUNT_DAX_ALWAYS 0x00000040
182178
#define EROFS_MOUNT_DAX_NEVER 0x00000080
179+
#define EROFS_MOUNT_DIRECT_IO 0x00000100
183180

184181
#define clear_opt(opt, option) ((opt)->mount_opt &= ~EROFS_MOUNT_##option)
185182
#define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option)
186183
#define test_opt(opt, option) ((opt)->mount_opt & EROFS_MOUNT_##option)
187184

188185
static inline bool erofs_is_fileio_mode(struct erofs_sb_info *sbi)
189186
{
190-
return IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) && sbi->fdev;
187+
return IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) && sbi->dif0.file;
191188
}
192189

193190
static inline bool erofs_is_fscache_mode(struct super_block *sb)
@@ -357,11 +354,9 @@ enum {
357354
};
358355

359356
struct erofs_map_dev {
360-
struct erofs_fscache *m_fscache;
357+
struct super_block *m_sb;
358+
struct erofs_device_info *m_dif;
361359
struct block_device *m_bdev;
362-
struct dax_device *m_daxdev;
363-
struct file *m_fp;
364-
u64 m_dax_part_off;
365360

366361
erofs_off_t m_pa;
367362
unsigned int m_deviceid;

0 commit comments

Comments
 (0)