1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
/*
* Copyright (C) 2025 Alibaba Cloud
*/
#include "erofs/importer.h"
#include "erofs/config.h"
#include "erofs/dedupe.h"
#include "erofs/inode.h"
#include "erofs/print.h"
#include "erofs/lock.h"
#include "erofs/xattr.h"
#include "liberofs_cache.h"
#include "liberofs_compress.h"
#include "liberofs_fragments.h"
#include "liberofs_metabox.h"
static EROFS_DEFINE_MUTEX(erofs_importer_global_mutex);
static bool erofs_importer_global_initialized;
void erofs_importer_preset(struct erofs_importer_params *params)
{
*params = (struct erofs_importer_params) {
.fixed_uid = -1,
.fixed_gid = -1,
.fsalignblks = 1,
.build_time = -1,
.max_compressed_extent_size =
EROFS_COMPRESSED_EXTENT_UNSPECIFIED,
};
}
void erofs_importer_global_init(void)
{
if (erofs_importer_global_initialized)
return;
erofs_mutex_lock(&erofs_importer_global_mutex);
if (!erofs_importer_global_initialized) {
erofs_inode_manager_init();
erofs_importer_global_initialized = true;
}
erofs_mutex_unlock(&erofs_importer_global_mutex);
}
int erofs_importer_init(struct erofs_importer *im)
{
struct erofs_sb_info *sbi = im->sbi;
struct erofs_importer_params *params = im->params;
const char *subsys = NULL;
int err;
erofs_importer_global_init();
subsys = "xattr";
err = erofs_xattr_init(sbi);
if (err)
goto out_err;
subsys = "compression";
err = z_erofs_compress_init(im);
if (err)
goto out_err;
if (params->fragments || cfg.c_extra_ea_name_prefixes ||
params->compress_dir) {
subsys = "packedfile";
if (!params->pclusterblks_packed)
params->pclusterblks_packed = params->pclusterblks_def;
err = erofs_packedfile_init(sbi, params->fragments ||
params->compress_dir);
if (err)
goto out_err;
}
subsys = "metadata";
err = erofs_metadata_init(sbi);
if (err)
goto out_err;
if (params->fragments) {
subsys = "dedupe_ext";
err = z_erofs_dedupe_ext_init();
if (err)
goto out_err;
}
if (params->dot_omitted)
erofs_sb_set_48bit(sbi);
if (params->build_time != -1) {
if (erofs_sb_has_48bit(sbi)) {
sbi->epoch = max_t(s64, 0, params->build_time - UINT32_MAX);
sbi->build_time = params->build_time - sbi->epoch;
} else {
sbi->epoch = params->build_time;
}
}
return 0;
out_err:
erofs_err("failed to initialize %s: %s", subsys, erofs_strerror(-err));
return err;
}
int erofs_importer_flush_all(struct erofs_importer *im)
{
struct erofs_sb_info *sbi = im->sbi;
unsigned int fsalignblks;
int err;
if (erofs_sb_has_metabox(sbi)) {
erofs_update_progressinfo("Handling metabox ...");
err = erofs_metabox_iflush(im);
if (err)
return err;
}
err = erofs_flush_packed_inode(im);
if (err)
return err;
err = erofs_metazone_flush(sbi);
if (err)
return err;
fsalignblks = im->params->fsalignblks ?
roundup_pow_of_two(im->params->fsalignblks) : 1;
sbi->primarydevice_blocks = roundup(erofs_mapbh(sbi->bmgr, NULL),
fsalignblks);
err = erofs_write_device_table(sbi);
if (err)
return err;
/* flush all buffers except for the superblock */
err = erofs_bflush(sbi->bmgr, NULL);
if (err)
return err;
return erofs_fixup_root_inode(im->root);
}
void erofs_importer_exit(struct erofs_importer *im)
{
struct erofs_sb_info *sbi = im->sbi;
z_erofs_dedupe_ext_exit();
erofs_metadata_exit(sbi);
erofs_packedfile_exit(sbi);
}
|