Linux仮想ファイルシステムの4つの主要オブジェクト(スーパーブロック、inode、dentry、ファイル)の関係

Linux仮想ファイルシステムの4つの主要オブジェクト(スーパーブロック、inode、dentry、ファイル)の関係

  [[378977]]

1. ファイルシステム

1. ファイルシステムとは何ですか?

ファイル情報の管理と保存を担当するオペレーティング システム内のソフトウェア構成は、ファイル管理システム、または略してファイル システムと呼ばれます。

通常、ファイル システムは、ファイルを簡単に検索およびアクセスできるようにファイルを保存および整理するためのメカニズムです。

ファイル システムは、ファイル ストレージ デバイス上のスペースを整理して割り当て、ファイルの保存と、保存されたファイルの保護および取得を担当するシステムです。

ユーザーのファイルの作成、ファイルの保存、読み取り、変更、ダンプ、ファイル アクセスの制御、ユーザーが使用しなくなったファイルの取り消しなどを担当します。

ファイルの種類が増えるにつれて、さまざまなファイル システムを統一的に管理および整理するために、さらに多くのファイル システムが追加されます。

2. Linux ファイルシステム

Linux では、次の図に示すように、ファイル システムを VFS (仮想ファイル システム) と特定のファイル システムの 2 つのレイヤーに分割します。

仮想通貨

VFS (Virtual Filesystem Switch) は、仮想ファイルシステムまたは仮想ファイルシステムスイッチと呼ばれます。これはカーネル ソフトウェア レイヤーであり、特定のファイル システムの上にある抽象レイヤーであり、Posix ファイル システムに関連するすべての呼び出しを処理するために使用されます。さまざまなファイル システムに共通のインターフェイスを提供できるため、上位レベルのアプリケーションは共通のインターフェイスを使用してさまざまなファイル システムにアクセスできるようになります。また、異なるファイル システム間の通信のための媒体も提供します。

VFS は実際のファイルシステムではありません。メモリ内にのみ存在し、外部ストレージスペースには存在しません。 VFS はシステムの起動時に作成され、システムのシャットダウン時に消えます。

VFS は、スーパーブロック、inode、dentry、vfsmount などの構造で構成されています。

Linux システムには、一般的な **ext2、ext3、ext4、sysfs、rootfs、proc...** など、多くのファイル システムが存在します。

2. VFS

1. LinuxアーキテクチャにおけるVFSの位置づけ

ユーザーの観点から見ると、Linux のファイル システムは主に 3 つの層に分かれています。

  • 1. 上位ファイルシステムのシステムコール(システムコール)
  • 2. 仮想ファイルシステムVFS(仮想ファイルシステム)層、
  • 3. VFS にマウントされたさまざまな実際のファイル システム。

Linux システム全体における VFS のアーキテクチャ上のビューは次のとおりです。

仮想通貨

Linux システムのユーザーは、アプリケーションのランタイム ライブラリとして GLIBC (POSIX 標準、GUN C ランタイム ライブラリ) を使用し、オペレーティング システムを通じてそれをシステム コール SCI (システム コール インターフェイス) に変換します。 SCI は、オペレーティング システム カーネルによって定義されたシステム コール インターフェイスです。この抽象化レイヤーにより、ユーザー プログラムの I/O 操作をカーネル インターフェイス呼び出しに変換できるようになります。

2. ユーザーはどのようにしてファイルを透過的に処理できますか?

各ファイルシステムは独立しており、独自の構成と操作方法を持っていることがわかります。ユーザーがすべてのファイル システムを理解することは不可能なので、ユーザーがファイルを透過的に処理できるようにするにはどうすればよいでしょうか?

たとえば、ファイルを書き込みたい場合、どのファイル システムを使用していても、具体的にどのように読み取るかに関係なく、直接読み取ることができます。ここで仮想ファイルシステムを導入する必要があります。

仮想ファイル システムは次のようになります。システムには、ext2、ext3、fat32、ntfs などの複数の「実際のファイル システム」が存在する可能性があります。たとえば、現在複数のパーティションがあり、各パーティションには異なる「実際のファイル システム」が存在する可能性があることがわかります。

たとえば、ext2、ext3、fat32 の 3 つのディスク パーティションがある場合、それぞれの「実際のファイル システム」の操作とデータ構造は異なる必要があります。では、ユーザーはどうすればそれらを透過的に使用できるのでしょうか?

このとき、中間層として VFS が必要になります。ユーザーは VFS と直接やり取りします。

VFS はメモリ内にのみ存在するソフトウェア メカニズムです。各システムの初期化中に、Linux はまずメモリ (つまり、ソース コード内の名前空間) 内に VFS ディレクトリ ツリーを構築します。

VFS の主な機能は、上位層アプリケーションを下位層のさまざまな呼び出し方法から保護し、統一された呼び出しインターフェイスを提供することです。 2 つ目は、さまざまなファイル システムの編成と管理を容易にすることです。

VFS は、POSIX API インターフェイスをさまざまなストレージ デバイスの特定のインターフェイス実装から分離する抽象化レイヤーを提供し、基盤となるファイル システム タイプとデバイス タイプを上位レベルのアプリケーションに対して透過的にします。

たとえば、読み取りと書き込みは、sys_read と sys_write として VFS にマップされます。その後、VFS は、操作している「実際のファイルシステム」(どのパーティション) に応じて、異なる実際の操作を実行できます。この技術もお馴染みの「フック構造」技術で対応しています。

実際、VFS は抽象的な struct 構造を提供し、特定のファイル システムごとに独自のフィールドと関数を入力することで、異種混合の問題を解決します (カーネルの多くのサブシステムがこのメカニズムを広範に使用しています)。

3. Linux仮想ファイルシステムの4つの主要オブジェクト

ファイルシステムを統一的に管理および整理するために、Linux はパブリック ルート ディレクトリとグローバル ファイルシステム ツリーを作成します。ファイル システム内のファイルにアクセスするには、まず、グローバル ファイル システム ツリーのルート ディレクトリの下にファイル システムをマウントする必要があります。このマウント プロセスはファイル システムのマウントと呼ばれ、マウントされたディレクトリはマウント ポイントと呼ばれます。

ディスク上の従来のファイル システムのレイアウトは次のとおりです。

上の図からわかるように、ファイル システムの先頭は通常、ディスク セクターで構成されるブート ブロックです。この部分の主な目的は、オペレーティング システムを起動することです。通常、オペレーティング システムの起動時にのみ使用されます。

次はスーパーブロックです。主に物理ディスク内のファイルシステム構造の関連情報を保存し、各部分のサイズを記述します。

最後に、i ノード ビットマップ、論理ブロック ビットマップ、i ノード、および論理ブロックが物理ディスク上に分散されます。

スーパーブロック、i-node、論理ブロックを効率的に管理するために、Linux はファイルシステムタイプ、inode、dentry など、いくつかの異なるデータ構造を作成します。

ファイル システム タイプは、特定のファイル システムの動作を指定します。データ構造を使用して、特定のファイル システム タイプのインスタンスを構築できます。また、インスタンスはスーパーブロックインスタンスとも呼ばれます。

スーパーブロックは、ファイルシステムの全体的な制御情報を反映します。スーパーブロックはさまざまな方法で存在できます。ディスクベースのファイルシステムの場合、特定の形式でディスクの固定領域(ファイルシステムの種類によって異なります)に存在します。ファイル システムがマウントされると、スーパーブロックの内容がディスクに読み込まれ、メモリ内に新しいスーパーブロックが構築されます。

inode は、ファイル システム オブジェクト内の一般的なメタデータ情報を反映します。 Dentry は、グローバル ファイル システム ツリー内のファイル システム オブジェクトの場所を反映します。

Linux はこれら 4 つのデータ構造間に関連する関連付けを行います。以下のように表示されます。

構造的関係

1. スーパーブロック

スーパー ブロック: スーパー ブロックはファイル システムに対応します (インストールされているファイル システムの種類は ext2 などです。ここでは VFS ではなく実際のファイル システムです)。

すでに述べたように、ファイル システムはこれらのファイルのデータ形式と操作を管理するために使用されます。システム ファイルには独自のファイル システムがあり、異なるディスク パーティションにも異なるファイル システムが存在する場合があります。スーパーブロックは独立したファイルシステム用です。ファイル システムの種類、サイズ、ステータスなどを保存します。

(「ファイルシステム」と「ファイルシステムタイプ」は異なります。ファイルシステムタイプには、多くのファイルシステム、つまり多くのスーパーブロックを含めることができます)

異なるファイル システムには異なる super_block があることがわかっているので、異なる super_block に対する操作は異なるはずであり、上記の抽象 struct 構造は次の super_block 構造で確認できます (たとえば、次の struct super_operations)。

  1. 1246 構造体スーパーブロック {
  2. 1247 構造体 list_head s_list; /* これを最初に保存します*/
  3. 1248 dev_t s_dev; /* 検索インデックス; kdev_t ではない */
  4. 1249 符号なしchar s_blocksize_bits;
  5. 1250 符号なしlong s_blocksize;
  6. 1251 loff_t s_maxbytes; /*最大ファイルサイズ*/
  7. 1252 構造体ファイルシステムタイプ *s_type;
  8. 1253 定数構造体 super_operations *s_op;
  9. 1254 定数構造体dquot_operations *dq_op;
  10. 1255 定数構造体 quotactl_ops *s_qcop;
  11. 1256 定数構造体 export_operations *s_export_op;
  12. 1257 符号なしlong s_flags;
  13. 1258 符号なしロング s_magic;
  14. 1259 構造体dentry *s_root;
  15. 1260 構造体 rw_semaphore s_umount;
  16. 1261整数s_count;
  17. 1262 アトミックt s_active;
  18. 1263 #ifdef CONFIG_SECURITY
  19. 1264 void *s_security;
  20. 1265 #終了
  21. 1266 定数構造体 xattr_handler **s_xattr;
  22. 1267
  23. 1268 構造体 list_head s_inodes; /*すべてのinode */
  24. 1269 構造体 hlist_bl_head s_anon; /* (nfs) エクスポート用の匿名 dentry */
  25. 1270 構造体list_head s_mounts; /* マウントリスト; fsでは使用できません*/
  26. 1271 構造体ブロックデバイス *s_bdev;
  27. 1272 構造体 backing_dev_info *s_bdi;
  28. 1273 構造体 mtd_info *s_mtd;
  29. 1274 構造体 hlist_node s_instances;
  30. 1275 構造体 quota_info s_dquot; /* ディスククォータ固有のオプション */
  31. 1276
  32. 1277 構造体 sb_writers s_writers;
  33. 1278
  34. 1279文字s_id[32]; /* 情報*/
  35. 1280 u8 s_uuid[16]; /* UUID */
  36. 1281
  37. 1282 void *s_fs_info; /* ファイルシステムのプライベート情報 */
  38. 1283 符号なし整数s_max_links;
  39. 1284 fmode_t s_mode;
  40. 1285
  41. 1286 /* c/m/atime粒度 ns)。
  42. 1287 2番目より悪くなることはない*/
  43. 1288 u32 s_time_gran;
  44. 1289
  45. 1290 /*
  46. 1291 *次のフィールド  VFS *のみ* ファイルシステム関係ない
  47. 1292 *ても。警告されていました。
  48. 1293 */
  49. 1294 構造体ミューテックス s_vfs_rename_mutex; /* クラッジ */
  50. 1295
  51. 1296 /*
  52. 1297 * ファイルシステムのサブタイプ。空でない場合はファイルシステムタイプフィールド
  53. 1298 * /proc/mountsでは"type.subtype"になります 
  54. 1299 */
  55. 1300文字*s_subtype;
  56. 1301
  57. 1302 /*
  58. 1303 *遅延ファイルシステムマウントオプションを保存しました。
  59. 1304 * ジェネリック_show_options()
  60. 1305 */
  61. 1306文字__rcu *s_options;
  62. 1307 定数構造体dentry_operations *s_d_op; /* dentriesデフォルトのd_op */
  63. 1308
  64. 1309 /*
  65. 1310 * cleancache保存プール識別子(-1 はなしを意味します)
  66. 1311 */
  67. 1312 int cleancache_poolid;
  68. 1313
  69. 1314 構造体シュリンク s_shrink; /* SBごとのシュリンクハンドル */
  70. 1315
  71. 1316 /* nlink == 0 だがまだ参照されているinode*/
  72. 1317 アトミックロングt s_remove_count;
  73. 1318
  74. 1319 /*読み取り専用マウント中*/
  75. 1320 int s_readonly_remount;
  76. 1321
  77. 1322 /* AIO 完了は割り込みコンテキストから延期されます*/
  78. 1323 構造体ワークキュー構造体 *s_dio_done_wq;
  79. 1324
  80. 1325 /*
  81. 1326 * lruリストを最後に保存する 構造常に
  82. 1327 * 個別のキャッシュラインを所有します。
  83. 1328 */
  84. 1329 構造体 list_lru s_dentry_lru ____cacheline_aligned_in_smp;
  85. 1330 構造体 list_lru s_inode_lru ____cacheline_aligned_in_smp;
  86. 1331 構造体 rcu_head rcu;
  87. 1332 };

説明フィールド:

フィールド 説明する
s_リストスーパーブロックのリンク リストへのポインター。この struct list_head は非常によく知られた構造体で、実際には接続関係に使用される prev フィールドと next フィールドが含まれています。カーネルは単一のシンプルな構造を使用して、すべての super_blocks をリンクします。
s_dev この特定のファイル システムのブロック デバイス識別子が含まれます。たとえば、/dev/hda1の場合、デバイス識別子は0x301です。
s_ブロックサイズ_ビット上記のサイズは占有するビット数です。例えば512バイトは9ビットです。
s_ブロックサイズファイルシステム内のデータブロックのサイズ(バイト単位)
s_最大バイト数最大許容ファイルサイズ(バイト)
構造体ファイルシステムタイプ *s_type ファイル システムの種類 (つまり、現在のファイル システムはどのタイプか。ext2 または fat32) では、「ファイル システム」と「ファイル システムの種類」を区別することが重要です。ファイル システム タイプには、多くのファイル システム、つまり多くの super_blocks を含めることができます。これについては後で説明します。
構造体スーパーオペレーション *s_op 特定のファイルシステム上のスーパーブロック操作のための特定の関数セットを指します。
構造体 dquot_operations *dq_op 特定のファイルシステム上のクォータ操作のための特定の関数セットを指します
構造体 quotactl_ops *s_qcop ディスククォータの設定方法、ユーザー空間からのリクエストの処理方法
s_フラグインストール識別
s_magic 他のファイルシステムと区別する識別子
s_ルートこの特定のファイルシステムのインストールディレクトリを指すディレクトリエントリ
s_umount スーパーブロックの読み取りと書き込み時に同期する
s_count スーパーブロックの使用回数
s_アクティブ参照カウント

スーパーブロック方式

  1.   
  2. 構造体スーパーオペレーション{
  3. //この関数は、指定されたスーパーブロックの下に新しいインデックスノードオブジェクトを作成して初期化します
  4. 構造体 inode *(*alloc_inode)(構造体 super_block *sb);
  5. //指定されたインデックスノードを解放します。
  6. void (*destroy_inode)(構造体inode *);
  7. //VFS はインデックス ノードが変更されたときにこの関数を呼び出します。
  8. void (*dirty_inode) (構造体inode *、 int flags);
  9. // 指定された inode をディスクに書き戻します。
  10. int (*write_inode) (構造体inode *、構造体writeback_control *wbc);
  11. //インデックスノードを削除します。
  12. int (*drop_inode) (構造体inode *);
  13.          
  14. void (*evict_inode) (構造体inode *);
  15. //スーパーブロックを解放するために使用される
  16. void (*put_super) (構造体 super_block *);
  17. // ファイル システムのデータ要素をディスク上のファイル システムと同期します。 wait パラメータは、操作が同期的かどうかを指定します。
  18. int (*sync_fs)(構造体 super_block *sb、 int wait);
  19. int (*freeze_fs) (構造体 super_block *);
  20. int (*unfreeze_fs) (構造体 super_block *);
  21. //ファイルシステムのステータスを取得します。ファイルシステム関連の統計情報をstatfsに格納する
  22. int (*statfs) (構造体dentry *、構造体kstatfs *);
  23. int (*remount_fs) (構造体 super_block *, int *, char *);
  24. void (*umount_begin) (構造体 super_block *);
  25.   
  26. int (*show_options)(構造体 seq_file *、構造体 dentry *);
  27. int (*show_devname)(構造体 seq_file *、構造体 dentry *);
  28. int (*show_path)(構造体 seq_file *、構造体 dentry *);
  29. int (*show_stats)(構造体 seq_file *、構造体 dentry *);
  30. #ifdef CONFIG_QUOTA
  31. ssize_t (*quota_read)(構造体 super_block *, int , char *, size_t, loff_t);
  32. ssize_t (*quota_write)(構造体 super_block *, int , const char *, size_t, loff_t);
  33. #終了
  34. int (*bdev_try_to_free_page)(構造体 super_block*、構造体 page*、gfp_t);
  35. long (*nr_cached_objects)(構造体 super_block *, int );
  36. long (*free_cached_objects)(struct super_block *, long, int );
  37. };

2. iノード

インデックス ノード inode: 実際のデータに関するいくつかの情報 (「メタデータ」と呼ばれる、ファイル属性の説明) が実際に保存されます。

たとえば、ファイル サイズ、デバイス ID、ユーザー ID、ユーザー グループ ID、ファイル モード、拡張属性、ファイルが読み取られたときまたは変更されたときのタイムスタンプ、リンクの数、コンテンツが保存されているディスク ブロックへのポインター、ファイル分類などです。

(データはメタデータ+データ自体に分かれていることに注意してください)

また、注意: inode には 2 つの種類があり、1 つは VFS の inode で、もう 1 つは特定のファイル システムの inode です。前者はメモリ内にあり、後者はディスク上にあります。したがって、毎回、ディスク上の inode が実際にメモリ内の inode に呼び出されてメモリが満たされるため、ディスク ファイルの inode は使用されていると見なされます。

inode はどのように生成されますか?

各 inode ノードのサイズは通常 128 バイトまたは 256 バイトです。 inode ノードの合計数はフォーマット時に指定され (最新の OS は動的に変更可能)、通常は 2KB ごとに 1 つの inode が設定されます。

一般的にファイルシステム内に2KB未満のファイルは少ないため、2KBごとに分割する予定です。通常、inode を使い切ることはできません。したがって、ファイルシステムがインストールされると、デフォルトの inode 数が設定され、後で実際のニーズに応じて変更されます。

inode 番号に注意してください。inode 番号は一意であり、異なるファイルを表します。実際、Linux では、ファイルは inode 番号を通じてアクセスされ、いわゆるファイル名はユーザーの便宜のためだけのものとなっています。

ファイルを開くと、まずシステムはファイル名に対応する inode 番号を見つけます。次に、inode 番号を通じて inode 情報を取得し、最後に inode を通じてファイル データが配置されているブロックを見つけます。これでファイルデータを処理できるようになりました。

inode とファイルの関係は何ですか?

ファイルが作成されると、そのファイルに inode が割り当てられます。 1 つの inode は 1 つの実際のファイルにのみ対応し、1 つのファイルには 1 つの inode のみが含まれます。最大 inode 数は最大ファイル数です。

  1. 527 構造体iノード{
  2. 528 umode_t i_mode; /* アクセス許可制御 */
  3. 529 符号なしショート i_opflags;
  4. 530 kuid_t i_uid; /* ユーザーID */
  5. 531 kgid_t i_gid; /* グループIDを使用する */
  6. 532 符号なし整数i_flags; /* ファイルシステムフラグ */
  7. 533
  8. 534 #ifdef CONFIG_FS_POSIX_ACL
  9. 535 構造体 posix_acl *i_acl;
  10. 536 構造体 posix_acl *i_default_acl;
  11. 537 #終了
  12. 538
  13. 539 定数構造体inode_operations *i_op; /*インデックスノード操作テーブル*/
  14. 540 構造体スーパーブロック *i_sb; /* 関連するスーパーブロック */
  15. 541 構造体アドレス空間 *i_mapping; /* 関連アドレスマッピング */
  16. 542
  17. 543 #ifdef CONFIG_SECURITY
  18. 544 void *i_security;
  19. 545 #終了
  20. 546
  21. 547 /* 統計データ、パスウォーキングからはアクセスされません*/
  22. 548 符号なしロング i_ino; /* インデックスノード番号 */
  23. 549 /*
  24. 550 * ファイルシステム  i_nlink を直接読み取ります。彼らは
  25. 551 * 変更のための次の関数:
  26. 552 *
  27. 553 * (設定| クリア | 増加 |削除)_nlink
  28. 554 * inode_(inc| dec )_link_count
  29. 555 */
  30. 556組合{
  31. 557 定数符号なしint i_nlink;
  32. 558 符号なし整数__i_nlink; /* ハードリンクの数 */
  33. 559 };
  34. 560 dev_t i_rdev; /* 実際のデバイス識別子 */
  35. 561 loff_t i_size;
  36. 562 構造体timespec i_atime; /* 最終アクセス時間 */
  37. 563 構造体timespec i_mtime; /* 最終更新時刻 */
  38. 564 構造体timespec i_ctime; /* 最終変更時刻 */
  39. 565 スピンロック_t i_lock; /* i_blocks、i_bytes、おそらくi_size */
  40. 566 符号なしショート i_bytes; /* 使用されたバイト数 */
  41. 567 符号なし整数i_blkbits;
  42. 568ブロックi_blocks; /* ファイル内のブロック数 */
  43. 569
  44. 570 #ifdef __NEED_I_SIZE_ORDERED
  45. 571 seqcount_t i_size_seqcount;
  46. 572 #終了
  47. 573
  48. 574 /* その他 */
  49. 575 符号なしロングi_state;
  50. 576 構造体ミューテックス i_mutex;
  51. 577
  52. 578 符号なしロング dirtied_when; /* jiffy 最初のダーティ化の最初の変更時間*/
  53. 579
  54. 580 構造体 hlist_node i_hash; /* ハッシュ値、検索効率を向上 */
  55. 581 構造体 list_head i_wb_list; /* バックアップデバイス IO リスト */
  56. 582 構造体list_head i_lru; /* inode LRU 未使用 inode リスト*/
  57. 583 構造体 list_head i_sb_list; /* ファイルシステム内のすべての inode のリストをリンクします */
  58. 584組合{
  59. 585 構造体 hlist_head i_dentry; /* ディレクトリネックレステーブル */
  60. 586 構造体 rcu_head i_rcu;
  61. 587 };
  62. 588 u64 i_バージョン;
  63. 589 アトミック i_count; /* 参照カウント */
  64. 590 アトミックt i_dio_count;
  65. 591 アトミック_t i_writecount; /* ライター数 */
  66. 592 定数構造体ファイル操作 *i_fop; /* 以前の ->i_op->default_file_ops ファイル操作*/
  67. 593 構造体ファイルロック *i_flock; /* ファイルロックリスト */
  68. 594 構造体アドレス空間i_data; /* inode によって読み書きされるページを示します */
  69. 595 #ifdef CONFIG_QUOTA
  70. 596 struct dquot *i_dquot[MAXQUOTAS];/* ノードディスククォータ */
  71. 597 #終了
  72. 598 構造体list_head i_devices; /* デバイスリスト(同じドライバーを共有するデバイスのリスト)*/
  73. 599組合{
  74. 600 構造体 pipe_inode_info *i_pipe; /* パイプライン情報 */
  75. 601 構造体ブロックデバイス *i_bdev; /* ブロックデバイスドライバーノード */
  76. 602 構造体 cdev *i_cdev; /* 文字デバイス ドライバー ノード */
  77. 603 };
  78. 604
  79. 605 __u32 i_生成; /* インデックスノードのバージョン番号 */
  80. 606
  81. 607 #ifdef CONFIG_FSNOTIFY
  82. 608 __u32 i_fsnotify_mask; /* この inode が関係するすべてのイベント */
  83. 609 構造体 hlist_head i_fsnotify_marks;
  84. 610 #終了
  85. 611
  86. 612 #ifdef CONFIG_IMA
  87. 613 アトミック_t i_readcount; /* 構造体ファイルは ROを開きます*/
  88. 614 #終了
  89. 615 void *i_private; /* fsまたはデバイス プライベート ポインター ユーザー プライベート データ*/
  90. 616 };

inode を管理する 4 つのリンク リストに注意してください。

  1. 静的構造体 hlist_head *inode_hashtable __read_mostly;

ノードメソッド

  1. 構造体inode_operations{
  2. struct dentry * (*検索) (struct inode *、struct dentry *、unsigned int );
  3. void * (*follow_link) (構造体 dentry *、構造体 nameidata *);
  4. int (*permission) (構造体inode *, int );
  5. 構造体 posix_acl * (*get_acl)(構造体 inode *, int );
  6.   
  7. int (*readlink) (struct dentry *, char __user *, int );
  8. void (*put_link) (構造体dentry *、構造体nameidata *、void *);
  9.   
  10. int (*作成) (構造体 inode *、構造体 dentry *、umode_t、bool);
  11. int (*link) (struct dentry *、struct inode *、struct dentry *);
  12. int (*unlink) (構造体inode *、構造体dentry *);
  13. int (*symlink) (構造体 inode *、構造体 dentry *、const char *);
  14. int (*mkdir) (構造体inode *、構造体dentry *、umode_t);
  15. int (*rmdir) (構造体 inode *、構造体 dentry *);
  16. int (*mknod) (構造体 inode *、構造体 dentry *、umode_t、dev_t);
  17. int (*名前変更) (構造体inode *、構造体dentry *、
  18. 構造体 inode *、構造体 dentry *);
  19. int (*rename2) (構造体inode *、構造体dentry *、
  20. 構造体 inode *、構造体 dentry *、符号なしint );
  21. int (*setattr) (構造体dentry *、構造体iattr *);
  22. int (*getattr) (構造体 vfsmount *mnt、構造体 dentry *、構造体 kstat *);
  23. int (*setxattr) (構造体dentry *、const char *、const void *、size_t、 int );
  24. ssize_t (*getxattr) (構造体dentry *、const char *、void *、size_t);
  25. ssize_t (*listxattr) (構造体dentry *、 char *、size_t);
  26. int (*removexattr) (構造体dentry *、const char *);
  27. int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 開始,
  28. u64 長さ);
  29. int (*update_time)(構造体inode *、構造体timespec *、 int );
  30. int (*atomic_open)(構造体inode *、構造体dentry *、
  31. 構造体ファイル *、符号なし open_flag、
  32. umode_t create_mode、 int *開かれました);
  33. int (*tmpfile) (構造体 inode *、構造体 dentry *、umode_t);
  34. int (*set_acl)(構造体inode *、構造体posix_acl *、 int );
  35. } ____キャッシュラインを揃える;

重要な結果のいくつかが分析されています。

方法意味
作成する() inode がディレクトリ ファイルを記述する場合、ディレクトリ内でファイルが作成されるか開かれると、カーネルはそのファイルの inode を作成する必要があります。 VFS は、inode の i_op->create() 関数を呼び出すことによって、新しい inode の作成を完了します。この関数の最初のパラメータはディレクトリの inode、2 番目のパラメータは開く新しいファイルの dentry、3 番目のパラメータはファイルのアクセス許可です。 inode が通常のファイルを記述している場合、inode は create 関数を呼び出すことはありません。
見上げる() 指定されたファイルの dentry を検索します。
リンク() 指定されたディレクトリにハードリンクを作成するために使用されます。このリンク関数は、最終的にはシステムコール link() によって呼び出されます。この関数の最初のパラメータは元のファイルの dentry、2 番目のパラメータは指定されたディレクトリの inode、3 番目のパラメータはリンクされたファイルの dentry です。
リンクを解除する () ディレクトリ内の指定されたハードリンクを削除します。このリンク解除関数は、最終的にはシステムコール unlink() によって呼び出されます。最初のパラメータはハードリンクが配置されているディレクトリの inode であり、2 番目のパラメータは削除するファイルの dentry です。
シンボリックリンク() 特定のディレクトリに新しいディレクトリを作成する
mkdir() 指定されたディレクトリの下にサブディレクトリを作成します。現在のディレクトリの inode は i_op->mkdir() を呼び出します。この関数は、mkdir() システムコールによって呼び出されます。最初のパラメータは指定されたディレクトリの inode、2 番目のパラメータはサブディレクトリの dentry、3 番目のパラメータはサブディレクトリの権限です。
rmdir() inode によって記述されたディレクトリから指定されたサブディレクトリを削除する場合、この関数は最終的にシステム コール rmdir() によって呼び出されます。
うなずく() 指定されたディレクトリにパイプ、デバイス ファイル、ソケットなどの特殊なファイルを作成します。

3) ディレクトリエントリ (dentry)

ディレクトリ エントリは、ファイルを記述する論理属性です。これらはメモリ内にのみ存在し、実際にはディスク上の記述に対応していません。より正確には、メモリ内に存在し、検索パフォーマンスを向上させるために設計されたディレクトリ エントリ キャッシュです。

フォルダーと最終ファイルは両方ともディレクトリ項目に属し、すべてのディレクトリ項目が一緒になって巨大なディレクトリ ツリーを形成することに注意してください。

たとえば、ファイル /home/xxx/yyy.txt を開くと、/、home、xxx、yyy.txt はすべてディレクトリ エントリになります。 VFS は検索時に、ディレクトリ エントリの層ごとに各ディレクトリ エントリに対応する inode を見つけ、次にディレクトリ エントリに沿って操作して最終的なファイルを見つけます。

注: ディレクトリもファイルです (したがって、対応する inode もあります)。ディレクトリを開くということは、実際にはディレクトリ ファイルを開くことを意味します。

  1. 108 構造体dentry {
  2. 109 /* RCU ルックアップがアクセスしたフィールド */
  3. 110 符号なし整数d_flags; /* d_lockによって保護されています*/
  4. 111 seqcount_t d_seq; /* dentry seqlock ごと */
  5. 112 構造体 hlist_bl_node d_hash; /* ハッシュリストを検索 */
  6. 113 構造体dentry *d_parent; /* 親ディレクトリ 親ディレクトリ */
  7. 114 構造体qstr d_name;
  8. 115 構造体inode *d_inode; / *名前属する場所- NULL   
  9. 116 * 負 このディレクトリエントリに関連付けられた inode */
  10. 117 符号なしchar d_iname[DNAME_INLINE_LEN]; /* 小さな名前 短いファイル名 */
  11. 118
  12. 119 /* 参照検索は以下も参照します */
  13. 120 構造体ロック参照 d_lockref; /* dentry ごとのロック参照カウント */
  14. 121 定数構造体dentry_operations *d_op; /* ディレクトリエントリ操作 */
  15. 122 構造体スーパーブロック *d_sb; /* dentry ツリールートこのディレクトリ エントリが属するファイル システムのスーパー ブロック (ディレクトリ エントリ ツリーのルート)*/
  16. 123 符号なしlong d_time; /* d_revalidate の再検証時間によって使用される*/
  17. 124 void *d_fsdata; /* fs 固有のデータ 特定のファイルシステムデータ */
  18. 125
  19. 126 構造体list_head d_lru; /* LRU リストは、LRU アルゴリズムによってリンクされた未使用のディレクトリのリンク リストです */
  20. 127 /*
  21. 128 * d_childd_rcuはメモリを共有できる
  22. 129 */
  23. 130組合{
  24. 131 構造体list_head d_child; /* 親リストのディレクトリエントリ子は、これを通じて親ディレクトリの d_subdirs に追加されます */
  25. 132 構造体 rcu_head d_rcu;
  26. 133 } d_u;
  27. 134 構造体list_head d_subdirs; /* 私たちの子ディレクトリはすべてこのディレクトリのリストの先頭です */
  28. 135 構造体 hlist_node d_alias; /* inode エイリアス リスト インデックス ノード エイリアス リスト*/
  29. 136 };

ディレクトリ エントリはファイルまたはディレクトリのいずれかを表し、ディレクトリは実際にはファイルであるため、有効な dentry 構造には inode 構造が必要です。したがって、dentry 構造体が有効である限り、そのポインタ d_inode は inode 構造体を指している必要があります。しかし、inode は複数のものに対応することができます。

全体の構造は実際には木です。私のデバイス モデル kobject をご覧になったことがあるなら、ディレクトリは実際にはファイル (kobject、inode) とカプセル化のレイヤーであることがわかるでしょう。ここでのいわゆるカプセル化は、主に 2 つのポインタを追加します。1 つは親ディレクトリを指し、もう 1 つはディレクトリに含まれるすべてのファイル (通常のファイルとディレクトリ) のリンク リスト ヘッダーを指します。

これは、ディレクトリ操作を実行する方法です (たとえば、前のディレクトリに戻るには 1 つのポインタ ステップ [..] のみが必要ですが、サブディレクトリに入るにはリンク リストのインデックス作成が必要であり、複数のステップが必要です)

Dentry 関連の操作 (inode にはすでに mkdir、rmdir、mknod などの操作が含まれています)

  1. 構造体dentry_operations{
  2. /* この関数は、ディレクトリ オブジェクトが有効かどうかを判断します。 VFS は、dcache からディレクトリ エントリを使用する準備ができたときにこの関数を呼び出します。 */
  3. int (*d_revalidate)(構造体dentry *、符号なしint );
  4. int (*d_weak_revalidate)(構造体dentry *、符号なしint );
  5. /* このディレクトリのハッシュ値を生成します。ディレクトリ エントリをハッシュ テーブルに追加する場合は、VFS はこの関数を呼び出します。 */
  6. int (*d_hash)(const struct dentry *, struct qstr *);
  7. /* この関数は、2 つのファイル名 name1 と name2 を比較します。この機能を使用するには、dcache_lock ロックを追加する必要があります。 */
  8. int (*d_compare)(const struct dentry *, const struct dentry *,
  9. 符号なしint 、const char *、const struct qstr *);
  10. /* d_count=0 の場合、VFS はこの関数を呼び出します。この関数を使用するには、dcache_lock を呼び出します。 */
  11. int (*d_delete)(const struct dentry *);
  12. /* VFS はディレクトリ オブジェクトを解放するときにこの関数を呼び出します。 */
  13. void (*d_release)(構造体dentry *);
  14. void (*d_prune)(構造体dentry *);
  15. /* VFS は、ディレクトリ エントリが inode を失ったときにこの関数を呼び出します。 */
  16. void (*d_iput)(構造体dentry *、構造体inode *);
  17. char *(*d_dname)(構造体dentry *, char *, int );
  18. 構造体 vfsmount *(*d_automount)(構造体 path *);
  19. int (*d_manage)(構造体dentry *, bool);
  20. } ____キャッシュラインを揃える;
  21.   

4) ファイルオブジェクト(ファイル)

ファイル オブジェクトは、プロセスが開いたファイルを表します。ファイルは複数のプロセスによって開くことができるため、ファイルに対して複数のファイル オブジェクトが存在する場合があります。しかし、ファイルは一意であるため、inode は一意であり、ディレクトリ エントリも固定されています。

プロセスは実際にはファイル記述子を通じてファイルを操作します。各ファイルには、読み書きされる次のバイト位置を示す 32 ビットの番号があります。この番号はファイル位置と呼ばれます。

通常、ファイルを開いた後、特別な場合を除き、開く位置は 0 から始まります。 Linux はファイル構造を使用して開いているファイルの場所を保存するため、ファイルは開いているファイルの説明と呼ばれます。ファイル構造は、システム オープン ファイル テーブルと呼ばれる二重リンク リストを形成します。

ファイル

  1. 775 構造体ファイル {
  2. 776組合{
  3. 777 構造体 llist_node fu_llist; /* ファイルシステムで開かれた各ファイルは二重リンクリストを形成します */
  4. 778 構造体 rcu_head fu_rcuhead;
  5. 779 } ふ_u;
  6. 780 構造体パス f_path;
  7. 781 #define f_dentry f_path.dentry
  8. 782 構造体inode *f_inode; /* キャッシュされた値 */
  9. 783 定数構造体ファイル操作 *f_op; /* ファイル操作テーブルへのポインタ */
  10. 784
  11. 785 /*
  12. 786 * f_ep_links、f_flagsを保護します。
  13. 787 * IRQ コンテキストから取得してはなりませ
  14. 788 */
  15. 789 スピンロック f_lock;
  16. 790 アトミックロングt f_count; /* ファイルオブジェクトの使用回数 */
  17. 791 符号なし整数f_flags; /* ファイルを開くときに指定されるフラグ */
  18. 792 fmode_t f_mode; /* ファイルアクセスモード(権限など) */
  19. 793 構造体ミューテックス f_pos_lock;
  20. 794 オフセット f_pos; /* ファイルの現在の変位 */
  21. 795 構造体 fown_struct f_owner;
  22. 796 定数構造体cred *f_cred;
  23. 797 構造体 file_ra_state f_ra; /* 事前読み取りステータス */
  24. 798
  25. 799 u64 f_バージョン; /* バージョン番号 */
  26. 800 #ifdef CONFIG_SECURITY
  27. 801 void *f_security; /* セキュリティモジュール */
  28. 802 #終了
  29. 803 /* tty ドライバ、およびおそらく他のドライバ必要*/
  30. 804 void *プライベートデータ; /* プライベートデータ */
  31. 805
  32. 806 #ifdef CONFIG_EPOLL
  33. 807 /* fs/eventpoll.cによってこのファイルへのすべてのフックをリンクするために使用されます*/
  34. 808 構造体 list_head f_ep_links;
  35. 809 構造体 list_head f_tfile_llink;
  36. 810 #endif /* #ifdef CONFIG_EPOLL */
  37. 811 struct address_space *f_mapping;/* ページキャッシュマッピング */
  38. 812 #ifdef CONFIG_DEBUG_WRITECOUNT
  39. 813 符号なしlong f_mnt_write_state;
  40. 814 #終了
  41. 815 } __attribute__((aligned(4))); /* 少なくとも何か変なものが 2OK だと判断する */

いくつかの重要なフィールドの説明に重点を置きます。

まず、f_flags、f_mode、f_pos は、現在ファイルを操作しているプロセスの制御情報を表します。これは非常に重要です。ファイルは複数のプロセスによって同時に開かれる可能性があり、各プロセスではファイルの操作は非同期であるため、これら 3 つのフィールドは非常に重要です。

参照カウント f_count の場合、プロセスのファイル記述子を閉じると、実際にはファイルは閉じられず、単に f_count が 1 減少するだけです。 f_count=0 の場合、実際に閉じます。 dup や fork などの操作の場合、 f_count が増加します。具体的な内容については後ほど説明します。

f_opも非常に重要です!すべてのファイルに関係する操作構造です。たとえば、ユーザーが read を使用すると、最終的には file_operations の read 操作が呼び出されますが、file_operations 構造は異なるファイル システムで同じではない可能性があります。重要な操作機能はリリース機能です。ユーザーが close を実行すると、実際にはカーネル内で release 関数が実行されます。この関数は f_count を 1 つだけ減らします。これは、ユーザーがファイルを閉じると、f_count が実際に 1 つ減少するという、上記で述べたことも説明しています。参照カウントが 0 になった場合にのみ、ファイルは閉じられます。

注: 二重リンク リストは、それぞれ「使用中」および「未使用」のファイル オブジェクトを管理するために使用されます。

ファイル構造体

上記のファイルは 1 つのファイルのみです。プロセス (ユーザー) では複数のファイルを同時に処理できるため、すべてのファイルを管理するには別の構造が必要です。

つまり、ユーザーがファイルテーブルを開く ---> files_struct

  1. 172 構造体ファイル_構造体 {
  2. 173 ATOMIC_Tカウント;
  3. 174 rwlock_t file_lock; /*以下のすべてのメンバーを保護します。 tsk-> alloc_lock *内の巣
  4. 175 int max_fds;
  5. 176 int max_fdset;
  6. 177 int next_fd;
  7. 178 struct file ** fd; / *現在のFDアレイ */
  8. 179 fd_set *close_on_exec;
  9. 180 fd_set *open_fds;
  10. 181 fd_set close_on_exec_init;
  11. 182 fd_set open_fds_init;
  12. 183 struct file * fd_array [nr_open_default];
  13. 184};

いくつかのフィールドを説明してください:

フィールド 説明する
カウント参照カウント
file_lock ロック、次のフィールドを保護します
max_fds 現在のファイルオブジェクトの最大数
max_fdset ファイル記述子の最大数
next_fd 割り当てられたファイル記述子の最大数 + 1
FD ファイルオブジェクトへのポインターは、一般に最後のフィールドFD_ARRRAYを指します。ファイルの数がnr_open_defaultを超えると、配列が再割り当てされ、この新しい配列ポインターを指します!
close_on_exec exec()を実行するときに閉じる必要があるファイル記述子
open_fds 開いたファイル記述子へのポインタ
close_on_exec_init exec()が実行されたときに閉じる必要があるファイル記述子の初期化値
open_fds_init ファイル記述子の初期値設定
FD_ARRAY ファイルオブジェクトポインターの初期化配列

fs_struct

上記のファイルとfiles_structは、プロセス関連ファイルの情報を記録しますが、プロセス自体については、独自の情報の一部は何で表されますか?ここでは、FS_STRUCT構造を使用します。

  1. 5 struct fs_struct {
  2. 6 ATOMIC_Tカウント;
  3. 7 rwlock_t lock;
  4. 8 int umask;
  5. 9 struct dentry * root、 * pwd、 * altroot;
  6. 10 struct vfsmount * rootmnt、 * pwdmnt、 * altrootmnt;
  7. 11};

いくつかのフィールドを説明してください:

フィールド説明する
カウント見積カウント
ロック保護ロック
umask ファイルを開くときのデフォルトのファイルアクセス権限
プロセスのルートディレクトリ
パスワードプロセスの現在の実行ディレクトリ
アルトルーユーザーセットの交換ルートディレクトリ

注:実際に実行している場合、これらの3つのディレクトリは同じファイルシステムにない場合があります。たとえば、プロセスのルートディレクトリは通常、「 /」ノードにインストールされているextファイルシステムですが、現在の作業ディレクトリは /etcにインストールされているファイルシステムであり、ルートディレクトリの交換も別のファイルシステムに含まれている場合があります。 rootmnt、pwdmnt、altrootmnt:上記の3つのインストールポイントに対応します。

ファイルメソッド(操作)file_operations

  1. struct file_operations {
  2. structモジュール *所有者;
  3. loff_t( *llseek)(struct file *、loff_t、 int );
  4. ssize_t( * read )(struct file *、 char __user *、size_t、loff_t *);
  5. ssize_t( *write)(struct file *、const char __user *、size_t、loff_t *);
  6. ssize_t( *aio_read)(struct kiocb *、const struct iovec *、unsigned long、loff_t);
  7. ssize_t( *aio_write)(struct kiocb *、const struct iovec *、unsigned long、loff_t);
  8. ssize_t( *read_iter)(struct kiocb *、struct iov_iter *);
  9. ssize_t( *write_iter)(struct kiocb *、struct iov_iter *);
  10. int ( *iterate)(struct file *、struct dir_context *);
  11. unsigned int ( *poll)(struct file *、struct poll_table_struct *);
  12. long( *locked_ioctl)(struct file *、unsigned int 、unsigned long);
  13. long( *compat_ioctl)(struct file *、unsigned int 、unsigned long);
  14. int ( *mmap)(struct file *、struct vm_area_struct *);
  15. int ( * open )(struct inode *、struct file *);
  16. int ( *flush)(struct file *、fl_owner_t id);
  17. int ( *release)(struct inode *、struct file *);
  18. int ( *fsync)(struct file *、loff_t、loff_t、 int datasync);
  19. int ( *aio_fsync)(struct kiocb *、 int datasync);
  20. int ( *fasync)( int 、struct file *、 int );
  21. int ( *lock)(struct file *、 int 、struct file_lock *);
  22. ssize_t( *sendpage)(struct file *、struct page *、 int 、size_t、loff_t *、 int );
  23. unsigned long( *get_unmapped_area)(struct file *、unsigned long、unsigned long、unsigned long、unsigned long);
  24. int (*check_flags)( int );
  25. int ( *flock)(struct file *、 int 、struct file_lock *);
  26. ssize_t( *splice_write)(struct pipe_inode_info *、struct file *、loff_t *、size_t、unsigned int );
  27. ssize_t( *splice_read)(struct file *、loff_t *、struct pipe_inode_info *、size_t、unsigned int );
  28. int ( *setLease)(struct file *、long、struct file_lock **);
  29. long( *fallocate)(struct file *file、 int mode、loff_t offset、
  30. loff_t len);
  31. int ( *show_fdinfo)(struct seq_file *m、struct file *f);
  32. };

上記は、米国のドライバー開発者にとって最も馴染みのあるものでなければならず、習得する必要があります。

フィールド説明する
所有者このファイル操作構造を所有するモジュールを指定するために使用されるモジュールは、通常この_Moduleを取ります。
llseek ファイルのオフセットを設定するために使用されます。最初のパラメーターは、操作するファイル、2番目のパラメーターはオフセット、3番目のパラメーターはオフセットが開始される位置(Seek_set、Seek_cur、Seek_endのいずれかを使用できます)です。
読むファイルからデータを読み取ります。最初のパラメーターはソースファイル、2番目のパラメーターは宛先文字列、3番目のパラメーターは読み取るバイトの総数を示し、4番目のパラメーターはソースファイルのオフセットからデータの読み取りを開始することを示します。システムCall read()によって呼び出されます。
書くファイルにデータを書き込みます。最初のパラメーターは宛先ファイル、2番目のパラメーターはソース文字列、3番目のパラメーターはデータに記述されるバイトの総数を示し、4番目のパラメーターは宛先ファイルのオフセットからデータを書き込む開始を示します。 System Call write()によって呼び出されました。
mmap 指定されたファイルを指定されたアドレススペースにマップします。システムによって呼び出されましたmmap();
開ける指定されたファイルを開き、ファイルを指定されたインデックスノードに関連付けます。 System Call open()によって呼び出されます。
リリース開くファイルを無料で解放すると、開いたファイルの参照カウント(f_count)が0の場合に関数が呼び出されます。
fsync バッファーデータにファイルをディスクに戻します。

4.プロセスとこれら4つの関係

プロセスを管理するためにカーネルで使用される構造は、task_structです。ファイルを開くプロセスには、上記の4つの重要なデータ構造が含まれます。

  1. ファイル
  2. fs_struct
  3. files_struct
  4. 名前空間

各プロセスには独自の名前空間があります。

FS_STRUCTは、現在の作業ディレクトリ、プロセスのルートディレクトリなど、プロセスとファイルシステムの構造的関係を表すために使用されます。

files_structは、現在のプロセスによって開かれたファイルを表すために使用されます。

開いたファイルごとに、ファイルオブジェクトで表されます。

Linuxでは、ファイル記述子がオープンファイルを表すためにしばしば使用され、この記述子の値は多くの場合、0以上の整数です。この整数は、実際にはファイルfils_structのファイル配列fdの添え字です。すべてのオープンファイルについて、これらのファイル記述子はopen_fdsビットマップに保存されます。

プロセスとスーパーブロック、ファイル、インデックスノード、ディレクトリ項目の関係

図から次のことがわかります。

  • このプロセスは、domain files-> task_structのfiles_structを使用して、現在開いているファイルオブジェクトを理解します。そして、通常呼び出すファイル記述子は、実際にはプロセスによって開かれたファイルオブジェクト配列のインデックス値です。
  • ファイルオブジェクトは、ドメインf_dentryを介して対応するデントリーオブジェクトを見つけ、次にデントリーオブジェクトのドメインd_inodeが対応するイノードを見つけます(スーパーブロックの情報はイノードを介して取得できるため、ファイルを操作する最終的な方法を取得できます。これはファイルを開くときにプロセスです。
  • ファイルオブジェクトに対応するファイル操作関数のリストは、INODEのドメインI_FOPを介して取得され、I_FOPは最終的にstruct super_operations *s_opを介して初期化されます。

VFSファイルシステム内のイノードとデントリーは、実際のファイルシステムのINODEおよびDENTRYと特定の関係を持っていますが、同等ではありません。

実際のディスクファイルのイノードとデントリは物理的な外部メモリに存在しますが、VFSのイノードとデントリはメモリに存在します。システムが特定の処理のために外部メモリでイノードとデントリの情報を読み取った後、メモリ内のイノードとデントリを生成します。

仮想ファイルシステムには、InodeおよびDentry構造もありますが、これは対応するルールに従ってシステムによって生成され、実際の外部メモリには存在しません。

V.ディスクおよびファイルシステム

ディスクがいくつかのパーティションに分割されているとし、各パーティションが異なるファイルシステムであるとします。

ディスクとファイルシステム

参照記事:csdn-xiaodao dao侵害と削除

https://blog.csdn.net/qq_16777851/article/details/82914514

http://www.360doc.com/content/12/0503/19/9555338_208437965.shtml

https://www.sohu.com/a/326449573_467784

この記事は、WeChat Publicアカウント「Yikou Linux」から転載されています。下のQRコードからフォローできます。この記事を転載するには、Yikou Linuxの公式アカウントにお問い合わせください。

<<:  インフラストラクチャを自動化する方法

>>:  IoTソリューションの導入を検討している企業にとってクラウドコンピューティングが重要な理由

推薦する

スマート交通におけるエッジコンピューティングの応用に関する簡単な分析

1. エッジコンピューティングとは何ですか?エッジ コンピューティングは、5G ネットワーク アーキ...

リベートウェブサイトは本質的に「受動的」であり、トラフィックの売買モデルは持続不可能である。

起業家ラウンドテーブル円卓会議ゲストFanli.com CEO 葛永昌氏Tongcheng.com ...

高級マホガニー家具O2Oウェブサイト運営口コミ共有は試してみる価値がある

月給5,000~50,000のこれらのプロジェクトはあなたの将来です現在、O2Oウェブサイトの運営に...

Baidu Statisticsを使用する際に注意すべき2つのポイント

ウェブマスター統計ツールは、ほぼすべてのウェブマスターが知って理解しなければならないツールです。現在...

SEOではキーワードを分析する必要はなく、オーディエンスを分析するだけで十分です。

このタイトルは、多くのいわゆる SEOER を間違いなく冷笑させるでしょう。なぜでしょうか? 多くの...

4月25日の百度の「騒動」について語り、百度のアルゴリズムを分析する

今日は4月26日です。昨日の午後(4月25日)のBaiduの「騒動」は、誰もが体験し、深く感じたはず...

クラウドコンピューティングが教育業界にもたらす力

COVID-19パンデミックは多くの分野に大きな混乱を引き起こしており、教育も例外ではありません。世...

SEO学習の混乱を解消する:「外部リンク+記事」は考えるだけではない

最近、業界の友人数人と SEO について話したところ、同僚の多くが「オフサイトとは外部リンク、オンサ...

マルチクラウド環境を監視する方法

今日の急速に成長するビジネス市場では、ユーザーはアプリケーションが常に利用可能で最新の状態であること...

Smarthost: 米国専用サーバーが 30% オフ、月額 48 ドルから、複数のモデル、10 のデータセンターから選択可能

Smarthost は現在、バレンタインデーに向けて米国サーバーのプロモーションを実施しています。す...

citynethost-$5/kvm/512m メモリ/20g SSD/1T トラフィック/トルコ

citynethost.com は特別価格の KVM ベースの VPS を提供しており、コンピュータ...

XiNiX - 年間 30 ドルの VPS/1g のメモリ/30g のハードディスク/1t のトラフィック/5 つのデータセンター

XiNiX は、実に長い歴史を持つ企業です。少なくとも、私がまだ仮想ホストで遊んでいたころから、この...

初心者向け科学: 分散とクラスター

1. 分散型Xiao Ming の会社には、システム A、システム B、システム C の 3 つのシ...

マンツアジアと中国の大手ディスプレイメーカーが共同で力を発揮し、テレビパネル照明の新記録を樹立

幅広い技術ポートフォリオを持ち、世界的に活躍するハイテク機器メーカーである Manz AG は、実践...