Lines Matching +full:pre +full:- +full:verified
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2017-2018 HUAWEI, Inc.
13 #include <linux/backing-dev.h>
34 KERN_SOH_ASCII, level, sb->s_id, &vaf); in _erofs_printk()
43 u32 len = 1 << EROFS_SB(sb)->blkszbits, crc; in erofs_superblock_csum_verify()
46 len -= EROFS_SUPER_OFFSET; in erofs_superblock_csum_verify()
47 len -= offsetof(struct erofs_super_block, checksum) + in erofs_superblock_csum_verify()
48 sizeof(dsb->checksum); in erofs_superblock_csum_verify()
50 /* skip .magic(pre-verified) and .checksum(0) fields */ in erofs_superblock_csum_verify()
51 crc = crc32c(0x5045B54A, (&dsb->checksum) + 1, len); in erofs_superblock_csum_verify()
52 if (crc == le32_to_cpu(dsb->checksum)) in erofs_superblock_csum_verify()
55 crc, le32_to_cpu(dsb->checksum)); in erofs_superblock_csum_verify()
56 return -EBADMSG; in erofs_superblock_csum_verify()
63 inode_init_once(&vi->vfs_inode); in erofs_inode_init_once()
76 return &vi->vfs_inode; in erofs_alloc_inode()
83 if (inode->i_op == &erofs_fast_symlink_iops) in erofs_free_inode()
84 kfree(inode->i_link); in erofs_free_inode()
85 kfree(vi->xattr_shared_xattrs); in erofs_free_inode()
89 /* read variable-sized metadata, offset will be aligned by 4-byte */
106 return ERR_PTR(-ENOMEM); in erofs_read_metadata()
111 cnt = min_t(int, sb->s_blocksize - erofs_blkoff(sb, *offset), in erofs_read_metadata()
112 len - i); in erofs_read_metadata()
128 if (!dsb->u1.available_compr_algs) in z_erofs_parse_cfgs()
132 return -EOPNOTSUPP; in z_erofs_parse_cfgs()
148 if (!sbi->devs->flatdev && !dif->path) { in erofs_init_device()
149 if (!dis->tag[0]) { in erofs_init_device()
151 return -EINVAL; in erofs_init_device()
153 dif->path = kmemdup_nul(dis->tag, sizeof(dis->tag), GFP_KERNEL); in erofs_init_device()
154 if (!dif->path) in erofs_init_device()
155 return -ENOMEM; in erofs_init_device()
159 fscache = erofs_fscache_register_cookie(sb, dif->path, 0); in erofs_init_device()
162 dif->fscache = fscache; in erofs_init_device()
163 } else if (!sbi->devs->flatdev) { in erofs_init_device()
165 filp_open(dif->path, O_RDONLY | O_LARGEFILE, 0) : in erofs_init_device()
166 bdev_file_open_by_path(dif->path, in erofs_init_device()
167 BLK_OPEN_READ, sb->s_type, NULL); in erofs_init_device()
169 if (file == ERR_PTR(-ENOTBLK)) in erofs_init_device()
170 return -EINVAL; in erofs_init_device()
175 dif->dax_dev = fs_dax_get_by_bdev(file_bdev(file), in erofs_init_device()
176 &dif->dax_part_off, NULL, NULL); in erofs_init_device()
177 if (!dif->dax_dev && test_opt(&sbi->opt, DAX_ALWAYS)) { in erofs_init_device()
179 dif->path); in erofs_init_device()
180 clear_opt(&sbi->opt, DAX_ALWAYS); in erofs_init_device()
182 } else if (!S_ISREG(file_inode(file)->i_mode)) { in erofs_init_device()
184 return -EINVAL; in erofs_init_device()
186 dif->file = file; in erofs_init_device()
189 dif->blocks = le32_to_cpu(dis->blocks_lo); in erofs_init_device()
190 dif->uniaddr = le32_to_cpu(dis->uniaddr_lo); in erofs_init_device()
191 sbi->total_blocks += dif->blocks; in erofs_init_device()
206 sbi->total_blocks = sbi->dif0.blocks; in erofs_scan_devices()
210 ondisk_extradevs = le16_to_cpu(dsb->extra_devices); in erofs_scan_devices()
212 if (sbi->devs->extra_devices && in erofs_scan_devices()
213 ondisk_extradevs != sbi->devs->extra_devices) { in erofs_scan_devices()
215 ondisk_extradevs, sbi->devs->extra_devices); in erofs_scan_devices()
216 return -EINVAL; in erofs_scan_devices()
219 if (test_opt(&sbi->opt, DAX_ALWAYS) && !sbi->dif0.dax_dev) { in erofs_scan_devices()
221 clear_opt(&sbi->opt, DAX_ALWAYS); in erofs_scan_devices()
226 if (!sbi->devs->extra_devices && !erofs_is_fscache_mode(sb)) in erofs_scan_devices()
227 sbi->devs->flatdev = true; in erofs_scan_devices()
229 sbi->device_id_mask = roundup_pow_of_two(ondisk_extradevs + 1) - 1; in erofs_scan_devices()
230 pos = le16_to_cpu(dsb->devt_slotoff) * EROFS_DEVT_SLOT_SIZE; in erofs_scan_devices()
231 down_read(&sbi->devs->rwsem); in erofs_scan_devices()
232 if (sbi->devs->extra_devices) { in erofs_scan_devices()
233 idr_for_each_entry(&sbi->devs->tree, dif, id) { in erofs_scan_devices()
242 err = -ENOMEM; in erofs_scan_devices()
246 err = idr_alloc(&sbi->devs->tree, dif, 0, 0, GFP_KERNEL); in erofs_scan_devices()
251 ++sbi->devs->extra_devices; in erofs_scan_devices()
258 up_read(&sbi->devs->rwsem); in erofs_scan_devices()
278 ret = -EINVAL; in erofs_read_superblock()
279 if (le32_to_cpu(dsb->magic) != EROFS_SUPER_MAGIC_V1) { in erofs_read_superblock()
284 sbi->blkszbits = dsb->blkszbits; in erofs_read_superblock()
285 if (sbi->blkszbits < 9 || sbi->blkszbits > PAGE_SHIFT) { in erofs_read_superblock()
286 erofs_err(sb, "blkszbits %u isn't supported", sbi->blkszbits); in erofs_read_superblock()
289 if (dsb->dirblkbits) { in erofs_read_superblock()
290 erofs_err(sb, "dirblkbits %u isn't supported", dsb->dirblkbits); in erofs_read_superblock()
294 sbi->feature_compat = le32_to_cpu(dsb->feature_compat); in erofs_read_superblock()
301 ret = -EINVAL; in erofs_read_superblock()
302 sbi->feature_incompat = le32_to_cpu(dsb->feature_incompat); in erofs_read_superblock()
303 if (sbi->feature_incompat & ~EROFS_ALL_FEATURE_INCOMPAT) { in erofs_read_superblock()
305 sbi->feature_incompat & ~EROFS_ALL_FEATURE_INCOMPAT); in erofs_read_superblock()
309 sbi->sb_size = 128 + dsb->sb_extslots * EROFS_SB_EXTSLOT_SIZE; in erofs_read_superblock()
310 if (sbi->sb_size > PAGE_SIZE - EROFS_SUPER_OFFSET) { in erofs_read_superblock()
312 sbi->sb_size); in erofs_read_superblock()
315 sbi->dif0.blocks = le32_to_cpu(dsb->blocks_lo); in erofs_read_superblock()
316 sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr); in erofs_read_superblock()
318 sbi->xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr); in erofs_read_superblock()
319 sbi->xattr_prefix_start = le32_to_cpu(dsb->xattr_prefix_start); in erofs_read_superblock()
320 sbi->xattr_prefix_count = dsb->xattr_prefix_count; in erofs_read_superblock()
321 sbi->xattr_filter_reserved = dsb->xattr_filter_reserved; in erofs_read_superblock()
323 sbi->islotbits = ilog2(sizeof(struct erofs_inode_compact)); in erofs_read_superblock()
324 if (erofs_sb_has_48bit(sbi) && dsb->rootnid_8b) { in erofs_read_superblock()
325 sbi->root_nid = le64_to_cpu(dsb->rootnid_8b); in erofs_read_superblock()
326 sbi->dif0.blocks = sbi->dif0.blocks | in erofs_read_superblock()
327 ((u64)le16_to_cpu(dsb->rb.blocks_hi) << 32); in erofs_read_superblock()
329 sbi->root_nid = le16_to_cpu(dsb->rb.rootnid_2b); in erofs_read_superblock()
331 sbi->packed_nid = le64_to_cpu(dsb->packed_nid); in erofs_read_superblock()
333 if (sbi->sb_size <= offsetof(struct erofs_super_block, in erofs_read_superblock()
335 return -EFSCORRUPTED; in erofs_read_superblock()
336 sbi->metabox_nid = le64_to_cpu(dsb->metabox_nid); in erofs_read_superblock()
337 if (sbi->metabox_nid & BIT_ULL(EROFS_DIRENT_NID_METABOX_BIT)) in erofs_read_superblock()
338 return -EFSCORRUPTED; /* self-loop detection */ in erofs_read_superblock()
340 sbi->inos = le64_to_cpu(dsb->inos); in erofs_read_superblock()
342 sbi->epoch = (s64)le64_to_cpu(dsb->epoch); in erofs_read_superblock()
343 sbi->fixed_nsec = le32_to_cpu(dsb->fixed_nsec); in erofs_read_superblock()
344 super_set_uuid(sb, (void *)dsb->uuid, sizeof(dsb->uuid)); in erofs_read_superblock()
346 if (dsb->volume_name[0]) { in erofs_read_superblock()
347 sbi->volume_name = kstrndup(dsb->volume_name, in erofs_read_superblock()
348 sizeof(dsb->volume_name), GFP_KERNEL); in erofs_read_superblock()
349 if (!sbi->volume_name) in erofs_read_superblock()
350 return -ENOMEM; in erofs_read_superblock()
353 /* parse on-disk compression configurations */ in erofs_read_superblock()
361 erofs_info(sb, "EXPERIMENTAL 48-bit layout support in use. Use at your own risk!"); in erofs_read_superblock()
365 erofs_info(sb, "[deprecated] fscache-based on-demand read feature in use. Use at your own risk!"); in erofs_read_superblock()
374 sbi->opt.cache_strategy = EROFS_ZIP_CACHE_READAROUND; in erofs_default_options()
375 sbi->opt.max_sync_decompress_pages = 3; in erofs_default_options()
376 sbi->opt.sync_decompress = EROFS_SYNC_DECOMPRESS_AUTO; in erofs_default_options()
379 set_opt(&sbi->opt, XATTR_USER); in erofs_default_options()
382 set_opt(&sbi->opt, POSIX_ACL); in erofs_default_options()
422 struct erofs_sb_info *sbi = fc->s_fs_info; in erofs_fc_set_dax_mode()
426 set_opt(&sbi->opt, DAX_ALWAYS); in erofs_fc_set_dax_mode()
427 clear_opt(&sbi->opt, DAX_NEVER); in erofs_fc_set_dax_mode()
430 set_opt(&sbi->opt, DAX_NEVER); in erofs_fc_set_dax_mode()
431 clear_opt(&sbi->opt, DAX_ALWAYS); in erofs_fc_set_dax_mode()
446 struct erofs_sb_info *sbi = fc->s_fs_info; in erofs_fc_parse_param()
459 set_opt(&sbi->opt, XATTR_USER); in erofs_fc_parse_param()
461 clear_opt(&sbi->opt, XATTR_USER); in erofs_fc_parse_param()
469 set_opt(&sbi->opt, POSIX_ACL); in erofs_fc_parse_param()
471 clear_opt(&sbi->opt, POSIX_ACL); in erofs_fc_parse_param()
478 sbi->opt.cache_strategy = result.uint_32; in erofs_fc_parse_param()
485 return -EINVAL; in erofs_fc_parse_param()
489 return -EINVAL; in erofs_fc_parse_param()
494 return -ENOMEM; in erofs_fc_parse_param()
495 dif->path = kstrdup(param->string, GFP_KERNEL); in erofs_fc_parse_param()
496 if (!dif->path) { in erofs_fc_parse_param()
498 return -ENOMEM; in erofs_fc_parse_param()
500 down_write(&sbi->devs->rwsem); in erofs_fc_parse_param()
501 ret = idr_alloc(&sbi->devs->tree, dif, 0, 0, GFP_KERNEL); in erofs_fc_parse_param()
502 up_write(&sbi->devs->rwsem); in erofs_fc_parse_param()
504 kfree(dif->path); in erofs_fc_parse_param()
508 ++sbi->devs->extra_devices; in erofs_fc_parse_param()
512 kfree(sbi->fsid); in erofs_fc_parse_param()
513 sbi->fsid = kstrdup(param->string, GFP_KERNEL); in erofs_fc_parse_param()
514 if (!sbi->fsid) in erofs_fc_parse_param()
515 return -ENOMEM; in erofs_fc_parse_param()
518 kfree(sbi->domain_id); in erofs_fc_parse_param()
519 sbi->domain_id = kstrdup(param->string, GFP_KERNEL); in erofs_fc_parse_param()
520 if (!sbi->domain_id) in erofs_fc_parse_param()
521 return -ENOMEM; in erofs_fc_parse_param()
532 set_opt(&sbi->opt, DIRECT_IO); in erofs_fc_parse_param()
534 clear_opt(&sbi->opt, DIRECT_IO); in erofs_fc_parse_param()
540 sbi->dif0.fsoff = result.uint_64; in erofs_fc_parse_param()
549 erofs_nid_t nid = EROFS_I(inode)->nid; in erofs_encode_fh()
559 fh[2] = inode->i_generation; in erofs_encode_fh()
562 nid = EROFS_I(parent)->nid; in erofs_encode_fh()
566 fh[5] = parent->i_generation; in erofs_encode_fh()
581 ((u64)fid->raw[0] << 32) | fid->raw[1])); in erofs_fh_to_dentry()
591 ((u64)fid->raw[3] << 32) | fid->raw[4])); in erofs_fh_to_parent()
603 return d_obtain_alias(erofs_iget(child->d_sb, nid)); in erofs_get_parent()
617 if (sbi->domain_id) in erofs_set_sysfs_name()
618 super_set_sysfs_name_generic(sb, "%s,%s", sbi->domain_id, in erofs_set_sysfs_name()
619 sbi->fsid); in erofs_set_sysfs_name()
620 else if (sbi->fsid) in erofs_set_sysfs_name()
621 super_set_sysfs_name_generic(sb, "%s", sbi->fsid); in erofs_set_sysfs_name()
624 bdi_dev_name(sb->s_bdi)); in erofs_set_sysfs_name()
635 sb->s_magic = EROFS_SUPER_MAGIC; in erofs_fc_fill_super()
636 sb->s_flags |= SB_RDONLY | SB_NOATIME; in erofs_fc_fill_super()
637 sb->s_maxbytes = MAX_LFS_FILESIZE; in erofs_fc_fill_super()
638 sb->s_op = &erofs_sops; in erofs_fc_fill_super()
640 sbi->blkszbits = PAGE_SHIFT; in erofs_fc_fill_super()
641 if (!sb->s_bdev) { in erofs_fc_fill_super()
642 sb->s_blocksize = PAGE_SIZE; in erofs_fc_fill_super()
643 sb->s_blocksize_bits = PAGE_SHIFT; in erofs_fc_fill_super()
656 return -EINVAL; in erofs_fc_fill_super()
659 sbi->dif0.dax_dev = fs_dax_get_by_bdev(sb->s_bdev, in erofs_fc_fill_super()
660 &sbi->dif0.dax_part_off, NULL, NULL); in erofs_fc_fill_super()
667 if (sb->s_blocksize_bits != sbi->blkszbits) { in erofs_fc_fill_super()
670 return -EINVAL; in erofs_fc_fill_super()
674 sb->s_blocksize = 1 << sbi->blkszbits; in erofs_fc_fill_super()
675 sb->s_blocksize_bits = sbi->blkszbits; in erofs_fc_fill_super()
676 } else if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) { in erofs_fc_fill_super()
678 return -EINVAL; in erofs_fc_fill_super()
682 if (sbi->dif0.fsoff) { in erofs_fc_fill_super()
683 if (sbi->dif0.fsoff & (sb->s_blocksize - 1)) in erofs_fc_fill_super()
685 sbi->dif0.fsoff, sb->s_blocksize); in erofs_fc_fill_super()
690 if (test_opt(&sbi->opt, DAX_ALWAYS) && sbi->blkszbits != PAGE_SHIFT) { in erofs_fc_fill_super()
692 clear_opt(&sbi->opt, DAX_ALWAYS); in erofs_fc_fill_super()
695 sb->s_time_gran = 1; in erofs_fc_fill_super()
696 sb->s_xattr = erofs_xattr_handlers; in erofs_fc_fill_super()
697 sb->s_export_op = &erofs_export_ops; in erofs_fc_fill_super()
699 if (test_opt(&sbi->opt, POSIX_ACL)) in erofs_fc_fill_super()
700 sb->s_flags |= SB_POSIXACL; in erofs_fc_fill_super()
702 sb->s_flags &= ~SB_POSIXACL; in erofs_fc_fill_super()
708 if (erofs_sb_has_fragments(sbi) && sbi->packed_nid) { in erofs_fc_fill_super()
709 inode = erofs_iget(sb, sbi->packed_nid); in erofs_fc_fill_super()
712 sbi->packed_inode = inode; in erofs_fc_fill_super()
715 inode = erofs_iget(sb, sbi->metabox_nid); in erofs_fc_fill_super()
718 sbi->metabox_inode = inode; in erofs_fc_fill_super()
721 inode = erofs_iget(sb, sbi->root_nid); in erofs_fc_fill_super()
725 if (!S_ISDIR(inode->i_mode)) { in erofs_fc_fill_super()
727 sbi->root_nid, inode->i_mode); in erofs_fc_fill_super()
729 return -EINVAL; in erofs_fc_fill_super()
731 sb->s_root = d_make_root(inode); in erofs_fc_fill_super()
732 if (!sb->s_root) in erofs_fc_fill_super()
733 return -ENOMEM; in erofs_fc_fill_super()
745 sbi->dir_ra_bytes = EROFS_DIR_RA_BYTES; in erofs_fc_fill_super()
746 erofs_info(sb, "mounted with root inode @ nid %llu.", sbi->root_nid); in erofs_fc_fill_super()
752 struct erofs_sb_info *sbi = fc->s_fs_info; in erofs_fc_get_tree()
755 if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid) in erofs_fc_get_tree()
762 if (ret == -ENOTBLK) { in erofs_fc_get_tree()
765 if (!fc->source) in erofs_fc_get_tree()
767 file = filp_open(fc->source, O_RDONLY | O_LARGEFILE, 0); in erofs_fc_get_tree()
770 sbi->dif0.file = file; in erofs_fc_get_tree()
772 if (S_ISREG(file_inode(sbi->dif0.file)->i_mode) && in erofs_fc_get_tree()
773 sbi->dif0.file->f_mapping->a_ops->read_folio) in erofs_fc_get_tree()
782 struct super_block *sb = fc->root->d_sb; in erofs_fc_reconfigure()
784 struct erofs_sb_info *new_sbi = fc->s_fs_info; in erofs_fc_reconfigure()
788 if (new_sbi->fsid || new_sbi->domain_id) in erofs_fc_reconfigure()
791 if (test_opt(&new_sbi->opt, POSIX_ACL)) in erofs_fc_reconfigure()
792 fc->sb_flags |= SB_POSIXACL; in erofs_fc_reconfigure()
794 fc->sb_flags &= ~SB_POSIXACL; in erofs_fc_reconfigure()
796 sbi->opt = new_sbi->opt; in erofs_fc_reconfigure()
798 fc->sb_flags |= SB_RDONLY; in erofs_fc_reconfigure()
806 fs_put_dax(dif->dax_dev, NULL); in erofs_release_device_info()
807 if (dif->file) in erofs_release_device_info()
808 fput(dif->file); in erofs_release_device_info()
809 erofs_fscache_unregister_cookie(dif->fscache); in erofs_release_device_info()
810 dif->fscache = NULL; in erofs_release_device_info()
811 kfree(dif->path); in erofs_release_device_info()
820 idr_for_each(&devs->tree, &erofs_release_device_info, NULL); in erofs_free_dev_context()
821 idr_destroy(&devs->tree); in erofs_free_dev_context()
827 erofs_free_dev_context(sbi->devs); in erofs_sb_free()
828 kfree(sbi->fsid); in erofs_sb_free()
829 kfree(sbi->domain_id); in erofs_sb_free()
830 if (sbi->dif0.file) in erofs_sb_free()
831 fput(sbi->dif0.file); in erofs_sb_free()
832 kfree(sbi->volume_name); in erofs_sb_free()
838 struct erofs_sb_info *sbi = fc->s_fs_info; in erofs_fc_free()
857 return -ENOMEM; in erofs_init_fs_context()
859 sbi->devs = kzalloc(sizeof(struct erofs_dev_context), GFP_KERNEL); in erofs_init_fs_context()
860 if (!sbi->devs) { in erofs_init_fs_context()
862 return -ENOMEM; in erofs_init_fs_context()
864 fc->s_fs_info = sbi; in erofs_init_fs_context()
866 idr_init(&sbi->devs->tree); in erofs_init_fs_context()
867 init_rwsem(&sbi->devs->rwsem); in erofs_init_fs_context()
869 fc->ops = &erofs_context_ops; in erofs_init_fs_context()
875 iput(sbi->packed_inode); in erofs_drop_internal_inodes()
876 sbi->packed_inode = NULL; in erofs_drop_internal_inodes()
877 iput(sbi->metabox_inode); in erofs_drop_internal_inodes()
878 sbi->metabox_inode = NULL; in erofs_drop_internal_inodes()
880 iput(sbi->managed_cache); in erofs_drop_internal_inodes()
881 sbi->managed_cache = NULL; in erofs_drop_internal_inodes()
889 if ((IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid) || in erofs_kill_sb()
890 sbi->dif0.file) in erofs_kill_sb()
895 fs_put_dax(sbi->dif0.dax_dev, NULL); in erofs_kill_sb()
898 sb->s_fs_info = NULL; in erofs_kill_sb()
909 erofs_free_dev_context(sbi->devs); in erofs_put_super()
910 sbi->devs = NULL; in erofs_put_super()
934 return -ENOMEM; in erofs_module_init()
980 struct super_block *sb = dentry->d_sb; in erofs_statfs()
983 buf->f_type = sb->s_magic; in erofs_statfs()
984 buf->f_bsize = sb->s_blocksize; in erofs_statfs()
985 buf->f_blocks = sbi->total_blocks; in erofs_statfs()
986 buf->f_bfree = buf->f_bavail = 0; in erofs_statfs()
987 buf->f_files = ULLONG_MAX; in erofs_statfs()
988 buf->f_ffree = ULLONG_MAX - sbi->inos; in erofs_statfs()
989 buf->f_namelen = EROFS_NAME_LEN; in erofs_statfs()
991 if (uuid_is_null(&sb->s_uuid)) in erofs_statfs()
992 buf->f_fsid = u64_to_fsid(!sb->s_bdev ? 0 : in erofs_statfs()
993 huge_encode_dev(sb->s_bdev->bd_dev)); in erofs_statfs()
995 buf->f_fsid = uuid_to_fsid(sb->s_uuid.b); in erofs_statfs()
1001 struct erofs_sb_info *sbi = EROFS_SB(root->d_sb); in erofs_show_options()
1002 struct erofs_mount_opts *opt = &sbi->opt; in erofs_show_options()
1011 erofs_param_cache_strategy[opt->cache_strategy].name); in erofs_show_options()
1019 if (sbi->fsid) in erofs_show_options()
1020 seq_printf(seq, ",fsid=%s", sbi->fsid); in erofs_show_options()
1021 if (sbi->domain_id) in erofs_show_options()
1022 seq_printf(seq, ",domain_id=%s", sbi->domain_id); in erofs_show_options()
1024 if (sbi->dif0.fsoff) in erofs_show_options()
1025 seq_printf(seq, ",fsoffset=%llu", sbi->dif0.fsoff); in erofs_show_options()
1036 truncate_inode_pages_final(&inode->i_data); in erofs_evict_inode()