Вы не найдете «обычных» вызовов функций из-за недавнего перехода на новый API монтирования файловой системы через «контекст файловой системы». Вы можете найти больше информации в соответствующем (довольно массивном) patchwork .
Я не собираюсь объяснять все это, поскольку документация ядра, на которую я ссылался выше, уже должна дать довольно хорошее объяснение (и я также не являюсь экспертом по внутреннему устройству Linux FS).
«Контекст файловой системы» - это в основном структура, содержащая полезную информацию, которая передается и обновляется постепенно по мере необходимости. Теперь происходит следующее: функция vfs_get_tree()
отвечает за создание монтируемого root файловой системы и сохранение его в структуре fs_context
, которая затем передается в do_new_mount_fc()
и используется для фактического монтирования.
(*) int vfs_get_tree(struct fs_context *fc);
Get or create the mountable root and superblock, using the parameters in
the filesystem context to select/configure the superblock. This invokes
the ->get_tree() method.
Итак, теперь в do_new_mount()
вы видите, что функция вызывается справа перед do_new_mount_fc()
:
fc = fs_context_for_mount(type, sb_flags);
put_filesystem(type);
if (IS_ERR(fc))
return PTR_ERR(fc);
if (subtype)
err = vfs_parse_fs_string(fc, "subtype",
subtype, strlen(subtype));
if (!err && name)
err = vfs_parse_fs_string(fc, "source", name, strlen(name));
if (!err)
err = parse_monolithic_mount_data(fc, data);
if (!err && !mount_capable(fc))
err = -EPERM;
if (!err)
err = vfs_get_tree(fc); // <<<<<<<<<<<<<<<<<<<<<<< HERE
if (!err)
err = do_new_mount_fc(fc, path, mnt_flags);
put_fs_context(fc);
return err;
}
Функция vfs_get_tree()
вызывает fc->ops->get_tree()
, который является методом, отвечающим за создание root
(если он еще не существует) и присвоение его fc->root
.
error = fc->ops->get_tree(fc); // Here fc->root gets assigned.
if (error < 0)
return error;
Переход на этот новый API еще не завершен для всех файловых систем. Для файловых систем, которые все еще используют старый API (например, ext4), функция fs_context_for_mount()
(вызываемая в начале в do_new_mount()
) создает контекст файловой системы через alloc_fs_context()
, который проверяет, поддерживает ли файловая система новый API. , а если нет, то использует устаревшую версию контекстных операций файловой системы по умолчанию (на самом деле, вы также можете увидеть комментарий в этой последней ссылке, в котором говорится: «ЗАДАЧИ: Сделайте так, чтобы все файловые системы поддерживали это безоговорочно» ).
Для get_tree()
устаревшей версией является legacy_get_tree()
, что действительно делает именно то, что вы ожидаете от вызова fc->fs_type->mount(...)
.
/*
* Get a mountable root with the legacy mount command.
*/
static int legacy_get_tree(struct fs_context *fc)
{
struct legacy_fs_context *ctx = fc->fs_private;
struct super_block *sb;
struct dentry *root;
root = fc->fs_type->mount(fc->fs_type, fc->sb_flags,
fc->source, ctx->legacy_data);
if (IS_ERR(root))
return PTR_ERR(root);
sb = root->d_sb;
BUG_ON(!sb);
fc->root = root;
return 0;
}
Рано или поздно все файловые системы будут обновлены для использования нового API с контекстом файловой системы, эти legacy_*
функции будут полностью удалены, и мы увидим метод init_fs_context
в ext4 file_system_type
.