比較的古いLinuxカーネルソースコードでは、はdo_new_mount()
を呼び出しvfs_kern_mount()
、最終的にはを実行しますmount_fs()
。そして、この関数は以下のように実際のファイルシステムの関数を呼び出します
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
struct dentry *root;
struct super_block *sb;
......
root = type->mount(type, flags, name, data);
......
sb = root->d_sb;
......
}
しかし、比較的新しいLinuxカーネルソースコードでは、代わりにdo_new_mount()
が呼び出さdo_new_mount_fc()
れ、この関数が上記のように実際のファイルシステムのマウント関数を呼び出す方法がわかりません。
今の仕組みを教えてください。
「ファイルシステムコンテキスト」を介した新しいファイルシステムマウントAPIへの最近の移行のため、「通常の」関数呼び出しは見つかりません。あなたは関連する(かなり大規模な)パッチワークでより多くの情報を見つけることができます。
上でリンクしたカーネルのドキュメントはすでにかなり良い説明をしているはずなので、全体を説明するつもりはありません(そして、私はLinux FS内部の専門家でもありません)。
「ファイルシステムコンテキスト」は基本的に、必要に応じて渡され、段階的に更新される有用な情報を含む構造です。つまり、vfs_get_tree()
関数はファイルシステムのマウント可能なルートを作成し、それを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への移行は、まだすべてのファイルシステムで完了しているわけではありません。まだ(たとえば、ext4のための)古いAPIを使用するファイルシステムについては、fs_context_for_mount()
(で最初に呼び出される関数はdo_new_mount()
)を介してファイルシステムのコンテキストを作成し、alloc_fs_context()
それはファイルシステムが新しいAPIをサポートしているかどうかをどのチェックし、そうでない場合、デフォルトのレガシーを使用していますファイルシステムコンテキスト操作のバージョン(実際、この最後のリンクには、「TODO:すべてのファイルシステムがこれを無条件にサポートするようにする」というコメントも表示されます)。
の場合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
メソッドが表示されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加