29b24f6ca112d drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:31 +0800 1) // SPDX-License-Identifier: GPL-2.0-only
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 2) /*
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 3) * Copyright (C) 2017-2018 HUAWEI, Inc.
592e7cd00bb9d fs/erofs/super.c (Alexander A. Klimov 2020-07-13 15:09:44 +0200 4) * https://www.huawei.com/
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 5) * Created by Gao Xiang <gaoxiang25@huawei.com>
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 6) */
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 7) #include <linux/module.h>
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 8) #include <linux/buffer_head.h>
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 9) #include <linux/statfs.h>
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 10) #include <linux/parser.h>
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 11) #include <linux/seq_file.h>
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 12) #include <linux/crc32c.h>
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 13) #include <linux/fs_context.h>
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 14) #include <linux/fs_parser.h>
6af7b4830569a drivers/staging/erofs/super.c (Gao Xiang 2019-01-14 19:40:25 +0800 15) #include "xattr.h"
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 16)
13f06f48f7bf8 drivers/staging/erofs/super.c (Chao Yu 2018-07-26 20:21:55 +0800 17) #define CREATE_TRACE_POINTS
13f06f48f7bf8 drivers/staging/erofs/super.c (Chao Yu 2018-07-26 20:21:55 +0800 18) #include <trace/events/erofs.h>
13f06f48f7bf8 drivers/staging/erofs/super.c (Chao Yu 2018-07-26 20:21:55 +0800 19)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 20) static struct kmem_cache *erofs_inode_cachep __read_mostly;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 21)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 22) void _erofs_err(struct super_block *sb, const char *function,
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 23) const char *fmt, ...)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 24) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 25) struct va_format vaf;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 26) va_list args;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 27)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 28) va_start(args, fmt);
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 29)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 30) vaf.fmt = fmt;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 31) vaf.va = &args;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 32)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 33) pr_err("(device %s): %s: %pV", sb->s_id, function, &vaf);
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 34) va_end(args);
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 35) }
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 36)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 37) void _erofs_info(struct super_block *sb, const char *function,
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 38) const char *fmt, ...)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 39) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 40) struct va_format vaf;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 41) va_list args;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 42)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 43) va_start(args, fmt);
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 44)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 45) vaf.fmt = fmt;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 46) vaf.va = &args;
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 47)
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 48) pr_info("(device %s): %pV", sb->s_id, &vaf);
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 49) va_end(args);
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 50) }
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 51)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 52) static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 53) {
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 54) struct erofs_super_block *dsb;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 55) u32 expected_crc, crc;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 56)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 57) dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET,
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 58) EROFS_BLKSIZ - EROFS_SUPER_OFFSET, GFP_KERNEL);
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 59) if (!dsb)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 60) return -ENOMEM;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 61)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 62) expected_crc = le32_to_cpu(dsb->checksum);
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 63) dsb->checksum = 0;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 64) /* to allow for x86 boot sectors and other oddities. */
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 65) crc = crc32c(~0, dsb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET);
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 66) kfree(dsb);
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 67)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 68) if (crc != expected_crc) {
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 69) erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected",
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 70) crc, expected_crc);
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 71) return -EBADMSG;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 72) }
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 73) return 0;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 74) }
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 75)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 76) static void erofs_inode_init_once(void *ptr)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 77) {
a5876e24f13f1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:56 +0800 78) struct erofs_inode *vi = ptr;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 79)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 80) inode_init_once(&vi->vfs_inode);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 81) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 82)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 83) static struct inode *erofs_alloc_inode(struct super_block *sb)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 84) {
a5876e24f13f1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:56 +0800 85) struct erofs_inode *vi =
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 86) kmem_cache_alloc(erofs_inode_cachep, GFP_KERNEL);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 87)
e2ff9f15e8ac8 drivers/staging/erofs/super.c (Vatsala Narang 2019-03-21 05:36:13 +0530 88) if (!vi)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 89) return NULL;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 90)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 91) /* zero out everything except vfs_inode */
a5876e24f13f1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:56 +0800 92) memset(vi, 0, offsetof(struct erofs_inode, vfs_inode));
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 93) return &vi->vfs_inode;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 94) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 95)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 96) static void erofs_free_inode(struct inode *inode)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 97) {
a5876e24f13f1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:56 +0800 98) struct erofs_inode *vi = EROFS_I(inode);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 99)
a2c75c8143eaa fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:59 +0800 100) /* be careful of RCU symlink path */
a2c75c8143eaa fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:59 +0800 101) if (inode->i_op == &erofs_fast_symlink_iops)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 102) kfree(inode->i_link);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 103) kfree(vi->xattr_shared_xattrs);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 104)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 105) kmem_cache_free(erofs_inode_cachep, vi);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 106) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 107)
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 108) static bool check_layout_compatibility(struct super_block *sb,
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 109) struct erofs_super_block *dsb)
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 110) {
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 111) const unsigned int feature = le32_to_cpu(dsb->feature_incompat);
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 112)
426a930891cf1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:53 +0800 113) EROFS_SB(sb)->feature_incompat = feature;
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 114)
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 115) /* check if current kernel meets all mandatory requirements */
426a930891cf1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:53 +0800 116) if (feature & (~EROFS_ALL_FEATURE_INCOMPAT)) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 117) erofs_err(sb,
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 118) "unidentified incompatible feature %x, please upgrade kernel version",
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 119) feature & ~EROFS_ALL_FEATURE_INCOMPAT);
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 120) return false;
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 121) }
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 122) return true;
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 123) }
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 124)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 125) #ifdef CONFIG_EROFS_FS_ZIP
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 126) /* read variable-sized metadata, offset will be aligned by 4-byte */
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 127) static void *erofs_read_metadata(struct super_block *sb, struct page **pagep,
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 128) erofs_off_t *offset, int *lengthp)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 129) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 130) struct page *page = *pagep;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 131) u8 *buffer, *ptr;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 132) int len, i, cnt;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 133) erofs_blk_t blk;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 134)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 135) *offset = round_up(*offset, 4);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 136) blk = erofs_blknr(*offset);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 137)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 138) if (!page || page->index != blk) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 139) if (page) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 140) unlock_page(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 141) put_page(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 142) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 143) page = erofs_get_meta_page(sb, blk);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 144) if (IS_ERR(page))
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 145) goto err_nullpage;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 146) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 147)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 148) ptr = kmap(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 149) len = le16_to_cpu(*(__le16 *)&ptr[erofs_blkoff(*offset)]);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 150) if (!len)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 151) len = U16_MAX + 1;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 152) buffer = kmalloc(len, GFP_KERNEL);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 153) if (!buffer) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 154) buffer = ERR_PTR(-ENOMEM);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 155) goto out;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 156) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 157) *offset += sizeof(__le16);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 158) *lengthp = len;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 159)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 160) for (i = 0; i < len; i += cnt) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 161) cnt = min(EROFS_BLKSIZ - (int)erofs_blkoff(*offset), len - i);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 162) blk = erofs_blknr(*offset);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 163)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 164) if (!page || page->index != blk) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 165) if (page) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 166) kunmap(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 167) unlock_page(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 168) put_page(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 169) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 170) page = erofs_get_meta_page(sb, blk);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 171) if (IS_ERR(page)) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 172) kfree(buffer);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 173) goto err_nullpage;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 174) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 175) ptr = kmap(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 176) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 177) memcpy(buffer + i, ptr + erofs_blkoff(*offset), cnt);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 178) *offset += cnt;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 179) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 180) out:
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 181) kunmap(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 182) *pagep = page;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 183) return buffer;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 184) err_nullpage:
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 185) *pagep = NULL;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 186) return page;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 187) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 188)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 189) static int erofs_load_compr_cfgs(struct super_block *sb,
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 190) struct erofs_super_block *dsb)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 191) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 192) struct erofs_sb_info *sbi;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 193) struct page *page;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 194) unsigned int algs, alg;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 195) erofs_off_t offset;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 196) int size, ret;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 197)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 198) sbi = EROFS_SB(sb);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 199) sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 200)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 201) if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 202) erofs_err(sb, "try to load compressed fs with unsupported algorithms %x",
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 203) sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 204) return -EINVAL;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 205) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 206)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 207) offset = EROFS_SUPER_OFFSET + sbi->sb_size;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 208) page = NULL;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 209) alg = 0;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 210) ret = 0;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 211)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 212) for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 213) void *data;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 214)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 215) if (!(algs & 1))
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 216) continue;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 217)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 218) data = erofs_read_metadata(sb, &page, &offset, &size);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 219) if (IS_ERR(data)) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 220) ret = PTR_ERR(data);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 221) goto err;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 222) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 223)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 224) switch (alg) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 225) case Z_EROFS_COMPRESSION_LZ4:
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 226) ret = z_erofs_load_lz4_config(sb, dsb, data, size);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 227) break;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 228) default:
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 229) DBG_BUGON(1);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 230) ret = -EFAULT;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 231) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 232) kfree(data);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 233) if (ret)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 234) goto err;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 235) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 236) err:
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 237) if (page) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 238) unlock_page(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 239) put_page(page);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 240) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 241) return ret;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 242) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 243) #else
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 244) static int erofs_load_compr_cfgs(struct super_block *sb,
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 245) struct erofs_super_block *dsb)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 246) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 247) if (dsb->u1.available_compr_algs) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 248) erofs_err(sb, "try to load compressed fs when compression is disabled");
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 249) return -EINVAL;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 250) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 251) return 0;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 252) }
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 253) #endif
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 254)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 255) static int erofs_read_superblock(struct super_block *sb)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 256) {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 257) struct erofs_sb_info *sbi;
fe7c2423570dc fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:10 +0800 258) struct page *page;
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 259) struct erofs_super_block *dsb;
7dd68b147d60e drivers/staging/erofs/super.c (Thomas Weißschuh 2018-09-10 21:41:14 +0200 260) unsigned int blkszbits;
fe7c2423570dc fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:10 +0800 261) void *data;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 262) int ret;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 263)
fe7c2423570dc fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:10 +0800 264) page = read_mapping_page(sb->s_bdev->bd_inode->i_mapping, 0, NULL);
517d6b9c6f71b fs/erofs/super.c (Wei Yongjun 2019-09-18 08:30:33 +0000 265) if (IS_ERR(page)) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 266) erofs_err(sb, "cannot read erofs superblock");
517d6b9c6f71b fs/erofs/super.c (Wei Yongjun 2019-09-18 08:30:33 +0000 267) return PTR_ERR(page);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 268) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 269)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 270) sbi = EROFS_SB(sb);
fe7c2423570dc fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:10 +0800 271)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 272) data = kmap(page);
fe7c2423570dc fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:10 +0800 273) dsb = (struct erofs_super_block *)(data + EROFS_SUPER_OFFSET);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 274)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 275) ret = -EINVAL;
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 276) if (le32_to_cpu(dsb->magic) != EROFS_SUPER_MAGIC_V1) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 277) erofs_err(sb, "cannot find valid erofs superblock");
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 278) goto out;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 279) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 280)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 281) sbi->feature_compat = le32_to_cpu(dsb->feature_compat);
de06a6a375414 fs/erofs/super.c (Gao Xiang 2021-03-29 09:23:05 +0800 282) if (erofs_sb_has_sb_chksum(sbi)) {
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 283) ret = erofs_superblock_csum_verify(sb, data);
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 284) if (ret)
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 285) goto out;
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 286) }
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 287)
3f7e6cae20645 fs/erofs/super.c (Wei Yongjun 2021-05-19 14:16:57 +0000 288) ret = -EINVAL;
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 289) blkszbits = dsb->blkszbits;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 290) /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 291) if (blkszbits != LOG_BLOCK_SIZE) {
bde545295b710 fs/erofs/super.c (Gao Xiang 2021-01-20 09:30:16 +0800 292) erofs_err(sb, "blkszbits %u isn't supported on this platform",
bde545295b710 fs/erofs/super.c (Gao Xiang 2021-01-20 09:30:16 +0800 293) blkszbits);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 294) goto out;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 295) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 296)
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 297) if (!check_layout_compatibility(sb, dsb))
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 298) goto out;
5efe5137f05bb drivers/staging/erofs/super.c (Gao Xiang 2019-06-13 16:35:41 +0800 299)
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 300) sbi->sb_size = 128 + dsb->sb_extslots * EROFS_SB_EXTSLOT_SIZE;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 301) if (sbi->sb_size > EROFS_BLKSIZ) {
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 302) erofs_err(sb, "invalid sb_extslots %u (more than a fs block)",
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 303) sbi->sb_size);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 304) goto out;
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 305) }
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 306) sbi->blocks = le32_to_cpu(dsb->blocks);
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 307) sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 308) #ifdef CONFIG_EROFS_FS_XATTR
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 309) sbi->xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 310) #endif
8a76568225dea fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:54 +0800 311) sbi->islotbits = ilog2(sizeof(struct erofs_inode_compact));
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 312) sbi->root_nid = le16_to_cpu(dsb->root_nid);
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 313) sbi->inos = le64_to_cpu(dsb->inos);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 314)
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 315) sbi->build_time = le64_to_cpu(dsb->build_time);
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 316) sbi->build_time_nsec = le32_to_cpu(dsb->build_time_nsec);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 317)
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 318) memcpy(&sb->s_uuid, dsb->uuid, sizeof(dsb->uuid));
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 319)
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 320) ret = strscpy(sbi->volume_name, dsb->volume_name,
0259f209487c8 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:00 +0800 321) sizeof(dsb->volume_name));
a64d9493f587f drivers/staging/erofs/super.c (Gao Xiang 2019-08-18 18:28:24 +0800 322) if (ret < 0) { /* -E2BIG */
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 323) erofs_err(sb, "bad volume name without NIL terminator");
a64d9493f587f drivers/staging/erofs/super.c (Gao Xiang 2019-08-18 18:28:24 +0800 324) ret = -EFSCORRUPTED;
a64d9493f587f drivers/staging/erofs/super.c (Gao Xiang 2019-08-18 18:28:24 +0800 325) goto out;
a64d9493f587f drivers/staging/erofs/super.c (Gao Xiang 2019-08-18 18:28:24 +0800 326) }
5d50538fc567c fs/erofs/super.c (Huang Jianan 2021-03-29 09:23:06 +0800 327)
5d50538fc567c fs/erofs/super.c (Huang Jianan 2021-03-29 09:23:06 +0800 328) /* parse on-disk compression configurations */
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 329) if (erofs_sb_has_compr_cfgs(sbi))
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 330) ret = erofs_load_compr_cfgs(sb, dsb);
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 331) else
14373711dd54b fs/erofs/super.c (Gao Xiang 2021-03-29 18:00:12 +0800 332) ret = z_erofs_load_lz4_config(sb, dsb, NULL, 0);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 333) out:
b858a4844cfba fs/erofs/super.c (Pratik Shinde 2019-11-04 10:49:37 +0800 334) kunmap(page);
fe7c2423570dc fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:10 +0800 335) put_page(page);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 336) return ret;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 337) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 338)
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 339) /* set up default EROFS parameters */
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 340) static void erofs_default_options(struct erofs_fs_context *ctx)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 341) {
5fb76bb04216f drivers/staging/erofs/super.c (Gao Xiang 2018-09-20 00:06:56 +0800 342) #ifdef CONFIG_EROFS_FS_ZIP
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 343) ctx->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 344) ctx->max_sync_decompress_pages = 3;
30048cdac4b92 fs/erofs/super.c (Huang Jianan 2021-03-17 11:54:48 +0800 345) ctx->readahead_sync_decompress = false;
5fb76bb04216f drivers/staging/erofs/super.c (Gao Xiang 2018-09-20 00:06:56 +0800 346) #endif
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 347) #ifdef CONFIG_EROFS_FS_XATTR
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 348) set_opt(ctx, XATTR_USER);
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 349) #endif
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 350) #ifdef CONFIG_EROFS_FS_POSIX_ACL
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 351) set_opt(ctx, POSIX_ACL);
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 352) #endif
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 353) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 354)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 355) enum {
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 356) Opt_user_xattr,
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 357) Opt_acl,
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 358) Opt_cache_strategy,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 359) Opt_err
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 360) };
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 361)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 362) static const struct constant_table erofs_param_cache_strategy[] = {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 363) {"disabled", EROFS_ZIP_CACHE_DISABLED},
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 364) {"readahead", EROFS_ZIP_CACHE_READAHEAD},
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 365) {"readaround", EROFS_ZIP_CACHE_READAROUND},
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 366) {}
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 367) };
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 368)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 369) static const struct fs_parameter_spec erofs_fs_parameters[] = {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 370) fsparam_flag_no("user_xattr", Opt_user_xattr),
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 371) fsparam_flag_no("acl", Opt_acl),
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 372) fsparam_enum("cache_strategy", Opt_cache_strategy,
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 373) erofs_param_cache_strategy),
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 374) {}
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 375) };
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 376)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 377) static int erofs_fc_parse_param(struct fs_context *fc,
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 378) struct fs_parameter *param)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 379) {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 380) struct erofs_fs_context *ctx __maybe_unused = fc->fs_private;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 381) struct fs_parse_result result;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 382) int opt;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 383)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 384) opt = fs_parse(fc, erofs_fs_parameters, param, &result);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 385) if (opt < 0)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 386) return opt;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 387)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 388) switch (opt) {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 389) case Opt_user_xattr:
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 390) #ifdef CONFIG_EROFS_FS_XATTR
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 391) if (result.boolean)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 392) set_opt(ctx, XATTR_USER);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 393) else
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 394) clear_opt(ctx, XATTR_USER);
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 395) #else
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 396) errorfc(fc, "{,no}user_xattr options not supported");
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 397) #endif
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 398) break;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 399) case Opt_acl:
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 400) #ifdef CONFIG_EROFS_FS_POSIX_ACL
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 401) if (result.boolean)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 402) set_opt(ctx, POSIX_ACL);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 403) else
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 404) clear_opt(ctx, POSIX_ACL);
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 405) #else
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 406) errorfc(fc, "{,no}acl options not supported");
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 407) #endif
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 408) break;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 409) case Opt_cache_strategy:
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 410) #ifdef CONFIG_EROFS_FS_ZIP
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 411) ctx->cache_strategy = result.uint_32;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 412) #else
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 413) errorfc(fc, "compression not supported, cache_strategy ignored");
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 414) #endif
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 415) break;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 416) default:
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 417) return -ENOPARAM;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 418) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 419) return 0;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 420) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 421)
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 422) #ifdef CONFIG_EROFS_FS_ZIP
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 423) static const struct address_space_operations managed_cache_aops;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 424)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 425) static int erofs_managed_cache_releasepage(struct page *page, gfp_t gfp_mask)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 426) {
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 427) int ret = 1; /* 0 - busy */
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 428) struct address_space *const mapping = page->mapping;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 429)
8b987bca2d096 drivers/staging/erofs/super.c (Gao Xiang 2018-12-05 21:23:13 +0800 430) DBG_BUGON(!PageLocked(page));
8b987bca2d096 drivers/staging/erofs/super.c (Gao Xiang 2018-12-05 21:23:13 +0800 431) DBG_BUGON(mapping->a_ops != &managed_cache_aops);
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 432)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 433) if (PagePrivate(page))
47e541a17ec7d drivers/staging/erofs/super.c (Gao Xiang 2018-07-29 13:34:58 +0800 434) ret = erofs_try_to_free_cached_page(mapping, page);
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 435)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 436) return ret;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 437) }
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 438)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 439) static void erofs_managed_cache_invalidatepage(struct page *page,
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 440) unsigned int offset,
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 441) unsigned int length)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 442) {
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 443) const unsigned int stop = length + offset;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 444)
8b987bca2d096 drivers/staging/erofs/super.c (Gao Xiang 2018-12-05 21:23:13 +0800 445) DBG_BUGON(!PageLocked(page));
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 446)
8b987bca2d096 drivers/staging/erofs/super.c (Gao Xiang 2018-12-05 21:23:13 +0800 447) /* Check for potential overflow in debug mode */
8b987bca2d096 drivers/staging/erofs/super.c (Gao Xiang 2018-12-05 21:23:13 +0800 448) DBG_BUGON(stop > PAGE_SIZE || stop < length);
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 449)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 450) if (offset == 0 && stop == PAGE_SIZE)
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 451) while (!erofs_managed_cache_releasepage(page, GFP_NOFS))
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 452) cond_resched();
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 453) }
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 454)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 455) static const struct address_space_operations managed_cache_aops = {
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 456) .releasepage = erofs_managed_cache_releasepage,
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 457) .invalidatepage = erofs_managed_cache_invalidatepage,
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 458) };
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 459)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 460) static int erofs_init_managed_cache(struct super_block *sb)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 461) {
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 462) struct erofs_sb_info *const sbi = EROFS_SB(sb);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 463) struct inode *const inode = new_inode(sb);
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 464)
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 465) if (!inode)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 466) return -ENOMEM;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 467)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 468) set_nlink(inode, 1);
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 469) inode->i_size = OFFSET_MAX;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 470)
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 471) inode->i_mapping->a_ops = &managed_cache_aops;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 472) mapping_set_gfp_mask(inode->i_mapping,
8494c29ffe22d drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:42 +0800 473) GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 474) sbi->managed_cache = inode;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 475) return 0;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 476) }
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 477) #else
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 478) static int erofs_init_managed_cache(struct super_block *sb) { return 0; }
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 479) #endif
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 480)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 481) static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 482) {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 483) struct inode *inode;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 484) struct erofs_sb_info *sbi;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 485) struct erofs_fs_context *ctx = fc->fs_private;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 486) int err;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 487)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 488) sb->s_magic = EROFS_SUPER_MAGIC;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 489)
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 490) if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 491) erofs_err(sb, "failed to set erofs blksize");
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 492) return -EINVAL;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 493) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 494)
a9f69bd555ccf drivers/staging/erofs/super.c (Shobhit Kukreti 2019-06-26 22:31:18 -0700 495) sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 496) if (!sbi)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 497) return -ENOMEM;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 498)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 499) sb->s_fs_info = sbi;
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 500) err = erofs_read_superblock(sb);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 501) if (err)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 502) return err;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 503)
5f0abea6ab6dd drivers/staging/erofs/super.c (Gao Xiang 2018-09-06 17:01:47 +0800 504) sb->s_flags |= SB_RDONLY | SB_NOATIME;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 505) sb->s_maxbytes = MAX_LFS_FILESIZE;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 506) sb->s_time_gran = 1;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 507)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 508) sb->s_op = &erofs_sops;
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 509) sb->s_xattr = erofs_xattr_handlers;
e7cda1ee94f46 fs/erofs/super.c (Chengguang Xu 2020-05-26 17:03:43 +0800 510)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 511) if (test_opt(ctx, POSIX_ACL))
516c115c9170f drivers/staging/erofs/super.c (Gao Xiang 2019-01-29 16:35:20 +0800 512) sb->s_flags |= SB_POSIXACL;
516c115c9170f drivers/staging/erofs/super.c (Gao Xiang 2019-01-29 16:35:20 +0800 513) else
516c115c9170f drivers/staging/erofs/super.c (Gao Xiang 2019-01-29 16:35:20 +0800 514) sb->s_flags &= ~SB_POSIXACL;
516c115c9170f drivers/staging/erofs/super.c (Gao Xiang 2019-01-29 16:35:20 +0800 515)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 516) sbi->ctx = *ctx;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 517)
e7e9a307be9d7 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:05 +0800 518) #ifdef CONFIG_EROFS_FS_ZIP
64094a04414f0 fs/erofs/super.c (Gao Xiang 2020-02-20 10:46:42 +0800 519) xa_init(&sbi->managed_pslots);
e7e9a307be9d7 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:05 +0800 520) #endif
e7e9a307be9d7 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:05 +0800 521)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 522) /* get the root inode */
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 523) inode = erofs_iget(sb, ROOT_NID(sbi), true);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 524) if (IS_ERR(inode))
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 525) return PTR_ERR(inode);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 526)
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 527) if (!S_ISDIR(inode->i_mode)) {
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 528) erofs_err(sb, "rootino(nid %llu) is not a directory(i_mode %o)",
4f761fa253b49 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:09 +0800 529) ROOT_NID(sbi), inode->i_mode);
94832d9399217 drivers/staging/erofs/super.c (Chengguang Xu 2019-01-23 14:12:25 +0800 530) iput(inode);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 531) return -EINVAL;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 532) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 533)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 534) sb->s_root = d_make_root(inode);
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 535) if (!sb->s_root)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 536) return -ENOMEM;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 537)
22fe04a77d104 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:39 +0800 538) erofs_shrinker_register(sb);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 539) /* sb->s_umount is already locked, SB_ACTIVE and SB_BORN are not set */
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 540) err = erofs_init_managed_cache(sb);
8d8a09b093d70 fs/erofs/super.c (Gao Xiang 2019-08-30 00:38:27 +0800 541) if (err)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 542) return err;
2497ee41295c7 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:03 +0800 543)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 544) erofs_info(sb, "mounted with root inode @ nid %llu.", ROOT_NID(sbi));
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 545) return 0;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 546) }
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 547)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 548) static int erofs_fc_get_tree(struct fs_context *fc)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 549) {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 550) return get_tree_bdev(fc, erofs_fc_fill_super);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 551) }
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 552)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 553) static int erofs_fc_reconfigure(struct fs_context *fc)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 554) {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 555) struct super_block *sb = fc->root->d_sb;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 556) struct erofs_sb_info *sbi = EROFS_SB(sb);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 557) struct erofs_fs_context *ctx = fc->fs_private;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 558)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 559) DBG_BUGON(!sb_rdonly(sb));
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 560)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 561) if (test_opt(ctx, POSIX_ACL))
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 562) fc->sb_flags |= SB_POSIXACL;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 563) else
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 564) fc->sb_flags &= ~SB_POSIXACL;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 565)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 566) sbi->ctx = *ctx;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 567)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 568) fc->sb_flags |= SB_RDONLY;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 569) return 0;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 570) }
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 571)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 572) static void erofs_fc_free(struct fs_context *fc)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 573) {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 574) kfree(fc->fs_private);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 575) }
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 576)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 577) static const struct fs_context_operations erofs_context_ops = {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 578) .parse_param = erofs_fc_parse_param,
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 579) .get_tree = erofs_fc_get_tree,
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 580) .reconfigure = erofs_fc_reconfigure,
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 581) .free = erofs_fc_free,
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 582) };
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 583)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 584) static int erofs_init_fs_context(struct fs_context *fc)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 585) {
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 586) fc->fs_private = kzalloc(sizeof(struct erofs_fs_context), GFP_KERNEL);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 587) if (!fc->fs_private)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 588) return -ENOMEM;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 589)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 590) /* set default mount options */
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 591) erofs_default_options(fc->fs_private);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 592)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 593) fc->ops = &erofs_context_ops;
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 594)
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 595) return 0;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 596) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 597)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 598) /*
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 599) * could be triggered after deactivate_locked_super()
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 600) * is called, thus including umount and failed to initialize.
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 601) */
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 602) static void erofs_kill_sb(struct super_block *sb)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 603) {
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 604) struct erofs_sb_info *sbi;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 605)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 606) WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 607)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 608) kill_block_super(sb);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 609)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 610) sbi = EROFS_SB(sb);
e2ff9f15e8ac8 drivers/staging/erofs/super.c (Vatsala Narang 2019-03-21 05:36:13 +0530 611) if (!sbi)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 612) return;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 613) kfree(sbi);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 614) sb->s_fs_info = NULL;
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 615) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 616)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 617) /* called when ->s_root is non-NULL */
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 618) static void erofs_put_super(struct super_block *sb)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 619) {
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 620) struct erofs_sb_info *const sbi = EROFS_SB(sb);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 621)
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 622) DBG_BUGON(!sbi);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 623)
22fe04a77d104 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:39 +0800 624) erofs_shrinker_unregister(sb);
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 625) #ifdef CONFIG_EROFS_FS_ZIP
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 626) iput(sbi->managed_cache);
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 627) sbi->managed_cache = NULL;
105d4ad857dcb drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:07 +0800 628) #endif
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 629) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 630)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 631) static struct file_system_type erofs_fs_type = {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 632) .owner = THIS_MODULE,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 633) .name = "erofs",
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 634) .init_fs_context = erofs_init_fs_context,
8f7acdae2cd4b drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:41 +0800 635) .kill_sb = erofs_kill_sb,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 636) .fs_flags = FS_REQUIRES_DEV,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 637) };
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 638) MODULE_ALIAS_FS("erofs");
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 639)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 640) static int __init erofs_module_init(void)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 641) {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 642) int err;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 643)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 644) erofs_check_ondisk_layout_definitions();
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 645)
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 646) erofs_inode_cachep = kmem_cache_create("erofs_inode",
a5876e24f13f1 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:56 +0800 647) sizeof(struct erofs_inode), 0,
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 648) SLAB_RECLAIM_ACCOUNT,
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 649) erofs_inode_init_once);
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 650) if (!erofs_inode_cachep) {
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 651) err = -ENOMEM;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 652) goto icache_err;
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 653) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 654)
22fe04a77d104 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:39 +0800 655) err = erofs_init_shrinker();
a15813126272e drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:04 +0800 656) if (err)
a15813126272e drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:04 +0800 657) goto shrinker_err;
a15813126272e drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:04 +0800 658)
524887347fcb6 fs/erofs/super.c (Gao Xiang 2021-04-10 03:06:30 +0800 659) erofs_pcpubuf_init();
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 660) err = z_erofs_init_zip_subsystem();
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 661) if (err)
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 662) goto zip_err;
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 663)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 664) err = register_filesystem(&erofs_fs_type);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 665) if (err)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 666) goto fs_err;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 667)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 668) return 0;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 669)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 670) fs_err:
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 671) z_erofs_exit_zip_subsystem();
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 672) zip_err:
22fe04a77d104 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:39 +0800 673) erofs_exit_shrinker();
a15813126272e drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:04 +0800 674) shrinker_err:
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 675) kmem_cache_destroy(erofs_inode_cachep);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 676) icache_err:
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 677) return err;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 678) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 679)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 680) static void __exit erofs_module_exit(void)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 681) {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 682) unregister_filesystem(&erofs_fs_type);
3883a79abd022 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:22:06 +0800 683) z_erofs_exit_zip_subsystem();
22fe04a77d104 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:39 +0800 684) erofs_exit_shrinker();
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 685)
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 686) /* Ensure all RCU free inodes are safe before cache is destroyed. */
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 687) rcu_barrier();
1c2dfbf9c2c86 fs/erofs/super.c (Gao Xiang 2019-09-04 10:08:55 +0800 688) kmem_cache_destroy(erofs_inode_cachep);
524887347fcb6 fs/erofs/super.c (Gao Xiang 2021-04-10 03:06:30 +0800 689) erofs_pcpubuf_exit();
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 690) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 691)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 692) /* get filesystem statistics */
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 693) static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 694) {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 695) struct super_block *sb = dentry->d_sb;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 696) struct erofs_sb_info *sbi = EROFS_SB(sb);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 697) u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 698)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 699) buf->f_type = sb->s_magic;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 700) buf->f_bsize = EROFS_BLKSIZ;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 701) buf->f_blocks = sbi->blocks;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 702) buf->f_bfree = buf->f_bavail = 0;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 703)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 704) buf->f_files = ULLONG_MAX;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 705) buf->f_ffree = ULLONG_MAX - sbi->inos;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 706)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 707) buf->f_namelen = EROFS_NAME_LEN;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 708)
6d1349c769ea2 fs/erofs/super.c (Al Viro 2020-09-18 16:45:50 -0400 709) buf->f_fsid = u64_to_fsid(id);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 710) return 0;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 711) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 712)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 713) static int erofs_show_options(struct seq_file *seq, struct dentry *root)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 714) {
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 715) struct erofs_sb_info *sbi __maybe_unused = EROFS_SB(root->d_sb);
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 716) struct erofs_fs_context *ctx __maybe_unused = &sbi->ctx;
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 717)
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 718) #ifdef CONFIG_EROFS_FS_XATTR
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 719) if (test_opt(ctx, XATTR_USER))
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 720) seq_puts(seq, ",user_xattr");
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 721) else
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 722) seq_puts(seq, ",nouser_xattr");
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 723) #endif
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 724) #ifdef CONFIG_EROFS_FS_POSIX_ACL
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 725) if (test_opt(ctx, POSIX_ACL))
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 726) seq_puts(seq, ",acl");
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 727) else
b17500a0fdbae drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:52 +0800 728) seq_puts(seq, ",noacl");
9c07b3b39dc77 drivers/staging/erofs/super.c (Chao Yu 2018-07-26 20:21:54 +0800 729) #endif
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 730) #ifdef CONFIG_EROFS_FS_ZIP
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 731) if (ctx->cache_strategy == EROFS_ZIP_CACHE_DISABLED)
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 732) seq_puts(seq, ",cache_strategy=disabled");
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 733) else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAHEAD)
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 734) seq_puts(seq, ",cache_strategy=readahead");
f57a3fe44995a fs/erofs/super.c (Chao Yu 2020-05-29 18:48:36 +0800 735) else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAROUND)
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 736) seq_puts(seq, ",cache_strategy=readaround");
4279f3f9889f2 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:49 +0800 737) #endif
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 738) return 0;
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 739) }
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 740)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 741) const struct super_operations erofs_sops = {
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 742) .put_super = erofs_put_super,
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 743) .alloc_inode = erofs_alloc_inode,
99634bf388db0 fs/erofs/super.c (Gao Xiang 2019-09-04 10:09:05 +0800 744) .free_inode = erofs_free_inode,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 745) .statfs = erofs_statfs,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 746) .show_options = erofs_show_options,
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 747) };
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 748)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 749) module_init(erofs_module_init);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 750) module_exit(erofs_module_exit);
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 751)
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 752) MODULE_DESCRIPTION("Enhanced ROM File System");
bc33d9f35da87 drivers/staging/erofs/super.c (Gao Xiang 2019-07-31 23:57:51 +0800 753) MODULE_AUTHOR("Gao Xiang, Chao Yu, Miao Xie, CONSUMER BG, HUAWEI Inc.");
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 754) MODULE_LICENSE("GPL");
ba2b77a820228 drivers/staging/erofs/super.c (Gao Xiang 2018-07-26 20:21:46 +0800 755)