Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'erofs-for-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs

Pull erofs updates from Gao Xiang:
"This cycle mainly addresses an issue out of some extended inode with
designated location, which are not generated by current mkfs but need
to handled at runtime anyway. The others are quite trivial ones.

- use HTTPS links instead of insecure HTTP ones;

- fix crossing page boundary on specific extended inodes;

- remove useless WQ_CPU_INTENSIVE flag for unbound wq;

- minor cleanup"

* tag 'erofs-for-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
erofs: remove WQ_CPU_INTENSIVE flag from unbound wq's
erofs: fold in used-once helper erofs_workgroup_unfreeze_final()
erofs: fix extended inode could cross boundary
erofs: Replace HTTP links with HTTPS ones

+100 -71
+1 -1
fs/erofs/compress.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 3 * Copyright (C) 2019 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #ifndef __EROFS_FS_COMPRESS_H
+1 -1
fs/erofs/data.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "internal.h"
+1 -1
fs/erofs/decompressor.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2019 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "compress.h"
+1 -1
fs/erofs/dir.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "internal.h"
+1 -1
fs/erofs/erofs_fs.h
··· 3 3 * EROFS (Enhanced ROM File System) on-disk format definition 4 4 * 5 5 * Copyright (C) 2017-2018 HUAWEI, Inc. 6 - * http://www.huawei.com/ 6 + * https://www.huawei.com/ 7 7 * Created by Gao Xiang <gaoxiang25@huawei.com> 8 8 */ 9 9 #ifndef __EROFS_FS_H
+80 -43
fs/erofs/inode.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "xattr.h" 8 8 9 9 #include <trace/events/erofs.h> 10 10 11 - /* no locking */ 12 - static int erofs_read_inode(struct inode *inode, void *data) 11 + /* 12 + * if inode is successfully read, return its inode page (or sometimes 13 + * the inode payload page if it's an extended inode) in order to fill 14 + * inline data if possible. 15 + */ 16 + static struct page *erofs_read_inode(struct inode *inode, 17 + unsigned int *ofs) 13 18 { 19 + struct super_block *sb = inode->i_sb; 20 + struct erofs_sb_info *sbi = EROFS_SB(sb); 14 21 struct erofs_inode *vi = EROFS_I(inode); 15 - struct erofs_inode_compact *dic = data; 16 - struct erofs_inode_extended *die; 22 + const erofs_off_t inode_loc = iloc(sbi, vi->nid); 17 23 18 - const unsigned int ifmt = le16_to_cpu(dic->i_format); 19 - struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); 20 - erofs_blk_t nblks = 0; 24 + erofs_blk_t blkaddr, nblks = 0; 25 + struct page *page; 26 + struct erofs_inode_compact *dic; 27 + struct erofs_inode_extended *die, *copied = NULL; 28 + unsigned int ifmt; 29 + int err; 30 + 31 + blkaddr = erofs_blknr(inode_loc); 32 + *ofs = erofs_blkoff(inode_loc); 33 + 34 + erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u", 35 + __func__, vi->nid, *ofs, blkaddr); 36 + 37 + page = erofs_get_meta_page(sb, blkaddr); 38 + if (IS_ERR(page)) { 39 + erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld", 40 + vi->nid, PTR_ERR(page)); 41 + return page; 42 + } 43 + 44 + dic = page_address(page) + *ofs; 45 + ifmt = le16_to_cpu(dic->i_format); 21 46 22 47 vi->datalayout = erofs_inode_datalayout(ifmt); 23 - 24 48 if (vi->datalayout >= EROFS_INODE_DATALAYOUT_MAX) { 25 49 erofs_err(inode->i_sb, "unsupported datalayout %u of nid %llu", 26 50 vi->datalayout, vi->nid); 27 - DBG_BUGON(1); 28 - return -EOPNOTSUPP; 51 + err = -EOPNOTSUPP; 52 + goto err_out; 29 53 } 30 54 31 55 switch (erofs_inode_version(ifmt)) { 32 56 case EROFS_INODE_LAYOUT_EXTENDED: 33 - die = data; 34 - 35 57 vi->inode_isize = sizeof(struct erofs_inode_extended); 58 + /* check if the inode acrosses page boundary */ 59 + if (*ofs + vi->inode_isize <= PAGE_SIZE) { 60 + *ofs += vi->inode_isize; 61 + die = (struct erofs_inode_extended *)dic; 62 + } else { 63 + const unsigned int gotten = PAGE_SIZE - *ofs; 64 + 65 + copied = kmalloc(vi->inode_isize, GFP_NOFS); 66 + if (!copied) { 67 + err = -ENOMEM; 68 + goto err_out; 69 + } 70 + memcpy(copied, dic, gotten); 71 + unlock_page(page); 72 + put_page(page); 73 + 74 + page = erofs_get_meta_page(sb, blkaddr + 1); 75 + if (IS_ERR(page)) { 76 + erofs_err(sb, "failed to get inode payload page (nid: %llu), err %ld", 77 + vi->nid, PTR_ERR(page)); 78 + kfree(copied); 79 + return page; 80 + } 81 + *ofs = vi->inode_isize - gotten; 82 + memcpy((u8 *)copied + gotten, page_address(page), *ofs); 83 + die = copied; 84 + } 36 85 vi->xattr_isize = erofs_xattr_ibody_size(die->i_xattr_icount); 37 86 38 87 inode->i_mode = le16_to_cpu(die->i_mode); ··· 118 69 /* total blocks for compressed files */ 119 70 if (erofs_inode_is_data_compressed(vi->datalayout)) 120 71 nblks = le32_to_cpu(die->i_u.compressed_blocks); 72 + 73 + kfree(copied); 121 74 break; 122 75 case EROFS_INODE_LAYOUT_COMPACT: 123 76 vi->inode_isize = sizeof(struct erofs_inode_compact); 77 + *ofs += vi->inode_isize; 124 78 vi->xattr_isize = erofs_xattr_ibody_size(dic->i_xattr_icount); 125 79 126 80 inode->i_mode = le16_to_cpu(dic->i_mode); ··· 163 111 erofs_err(inode->i_sb, 164 112 "unsupported on-disk inode version %u of nid %llu", 165 113 erofs_inode_version(ifmt), vi->nid); 166 - DBG_BUGON(1); 167 - return -EOPNOTSUPP; 114 + err = -EOPNOTSUPP; 115 + goto err_out; 168 116 } 169 117 170 118 if (!nblks) ··· 172 120 inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9; 173 121 else 174 122 inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK; 175 - return 0; 123 + return page; 176 124 177 125 bogusimode: 178 126 erofs_err(inode->i_sb, "bogus i_mode (%o) @ nid %llu", 179 127 inode->i_mode, vi->nid); 128 + err = -EFSCORRUPTED; 129 + err_out: 180 130 DBG_BUGON(1); 181 - return -EFSCORRUPTED; 131 + kfree(copied); 132 + unlock_page(page); 133 + put_page(page); 134 + return ERR_PTR(err); 182 135 } 183 136 184 137 static int erofs_fill_symlink(struct inode *inode, void *data, ··· 203 146 if (!lnk) 204 147 return -ENOMEM; 205 148 206 - m_pofs += vi->inode_isize + vi->xattr_isize; 149 + m_pofs += vi->xattr_isize; 207 150 /* inline symlink data shouldn't cross page boundary as well */ 208 151 if (m_pofs + inode->i_size > PAGE_SIZE) { 209 152 kfree(lnk); ··· 224 167 225 168 static int erofs_fill_inode(struct inode *inode, int isdir) 226 169 { 227 - struct super_block *sb = inode->i_sb; 228 170 struct erofs_inode *vi = EROFS_I(inode); 229 171 struct page *page; 230 - void *data; 231 - int err; 232 - erofs_blk_t blkaddr; 233 172 unsigned int ofs; 234 - erofs_off_t inode_loc; 173 + int err = 0; 235 174 236 175 trace_erofs_fill_inode(inode, isdir); 237 - inode_loc = iloc(EROFS_SB(sb), vi->nid); 238 - blkaddr = erofs_blknr(inode_loc); 239 - ofs = erofs_blkoff(inode_loc); 240 176 241 - erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u", 242 - __func__, vi->nid, ofs, blkaddr); 243 - 244 - page = erofs_get_meta_page(sb, blkaddr); 245 - 246 - if (IS_ERR(page)) { 247 - erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld", 248 - vi->nid, PTR_ERR(page)); 177 + /* read inode base data from disk */ 178 + page = erofs_read_inode(inode, &ofs); 179 + if (IS_ERR(page)) 249 180 return PTR_ERR(page); 250 - } 251 - 252 - DBG_BUGON(!PageUptodate(page)); 253 - data = page_address(page); 254 - 255 - err = erofs_read_inode(inode, data + ofs); 256 - if (err) 257 - goto out_unlock; 258 181 259 182 /* setup the new inode */ 260 183 switch (inode->i_mode & S_IFMT) { ··· 247 210 inode->i_fop = &erofs_dir_fops; 248 211 break; 249 212 case S_IFLNK: 250 - err = erofs_fill_symlink(inode, data, ofs); 213 + err = erofs_fill_symlink(inode, page_address(page), ofs); 251 214 if (err) 252 215 goto out_unlock; 253 216 inode_nohighmem(inode);
+1 -1
fs/erofs/internal.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #ifndef __EROFS_INTERNAL_H
+1 -1
fs/erofs/namei.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "xattr.h"
+1 -1
fs/erofs/super.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include <linux/module.h>
+4 -12
fs/erofs/utils.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "internal.h" ··· 127 127 return count; 128 128 } 129 129 130 - static void erofs_workgroup_unfreeze_final(struct erofs_workgroup *grp) 131 - { 132 - erofs_workgroup_unfreeze(grp, 0); 133 - __erofs_workgroup_free(grp); 134 - } 135 - 136 130 static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, 137 131 struct erofs_workgroup *grp) 138 132 { ··· 156 162 */ 157 163 DBG_BUGON(xa_erase(&sbi->managed_pslots, grp->index) != grp); 158 164 159 - /* 160 - * If managed cache is on, last refcount should indicate 161 - * the related workstation. 162 - */ 163 - erofs_workgroup_unfreeze_final(grp); 165 + /* last refcount should be connected with its managed pslot. */ 166 + erofs_workgroup_unfreeze(grp, 0); 167 + __erofs_workgroup_free(grp); 164 168 return true; 165 169 } 166 170
+1 -1
fs/erofs/xattr.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include <linux/security.h>
+1 -1
fs/erofs/xattr.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #ifndef __EROFS_XATTR_H
+3 -3
fs/erofs/zdata.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "zdata.h" ··· 43 43 static inline int z_erofs_init_workqueue(void) 44 44 { 45 45 const unsigned int onlinecpus = num_possible_cpus(); 46 - const unsigned int flags = WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE; 47 46 48 47 /* 49 48 * no need to spawn too many threads, limiting threads could minimum 50 49 * scheduling overhead, perhaps per-CPU threads should be better? 51 50 */ 52 - z_erofs_workqueue = alloc_workqueue("erofs_unzipd", flags, 51 + z_erofs_workqueue = alloc_workqueue("erofs_unzipd", 52 + WQ_UNBOUND | WQ_HIGHPRI, 53 53 onlinecpus + onlinecpus / 4); 54 54 return z_erofs_workqueue ? 0 : -ENOMEM; 55 55 }
+1 -1
fs/erofs/zdata.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 3 * Copyright (C) 2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #ifndef __EROFS_FS_ZDATA_H
+1 -1
fs/erofs/zmap.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2018-2019 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #include "internal.h"
+1 -1
fs/erofs/zpvec.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 3 * Copyright (C) 2018 HUAWEI, Inc. 4 - * http://www.huawei.com/ 4 + * https://www.huawei.com/ 5 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 6 */ 7 7 #ifndef __EROFS_FS_ZPVEC_H