web-dev-qa-db-ja.com

ファイルを保存するとき、メタデータはどこに行きますか?

たとえば、ジョニーがEMPTYファイルを作成するとします。いわゆる foobar.py。ジョニーが実行を許可すると、彼はchmod 755 foobar.py。ファイルには現在、次のメタデータが含まれています。

-rw-r--r-- 1 johnny staff    0 Dec 27 22:53 foobar.py

すべてのメタデータはそのファイルのどこに保存されていますか?ファイルのサイズが0であるため、別のドライブに転送するときにメタデータをどのように保持しますか?

28
juniorRubyist

そのファイルには保存されません。これはファイルシステムに保存され、すべてのパラメーターは手動で1つずつコピーされます(一部はまったくコピーできません)。

つまり、ほとんどのオペレーティングシステムには、「メタデータを含むファイルのコピー」の呼び出しはありません。ファイルコピープログラムは、foobar.pyという名前の新しいファイルを作成し、0バイトのデータ全体をコピーして、 utime() または を使用しますSetFileTime() を使用して、変更時刻を元の時刻と同じようにします。同様に、ファイル許可は、chmod()を使用してそれらを新たに設定するか、POSIX ACL属性をコピーすることによって「コピー」されます。

一部のメタデータはコピーされません。所有権を設定するにはroot権限が必要なので、他の誰かのファイルのコピーはあなたに属し、yourディスククォータを占有します。 UNIXでctime(属性変更時間)を手動で設定することはできません。 btime(birth/creation time)も通常コピーされません。

cp -a foo bar(メタデータをコピーする)とcp foo bar(しない)を比較します。

 $ strace -v cp foo bar 
…
 open( "foo"、O_RDONLY)= 3 
 open( "bar"、O_WRONLY | O_TRUNC)= 4 
 read(3、 "test\n"、131072)= 5 
 write(4、 "test\n"、5)= 5 
 read(3、 ""、 131072)= 0 
 close(4)= 0 
 close(3)= 0 
…
 $ strace -v cp -a foo bar 
…
-元のメタデータが取得されます
 lstat( "foo"、{st_dev = makedev(254、0 )、st_ino = 60569468、st_mode = S_IFREG | 0644、
 st_nlink = 1、st_uid = 1000、st_gid = 1000、st_blksize = 4096、st_blocks = 8、
 st_size = 5、st_atime = 2016- 12-28T09:16:59 + 0200.879714332、
 st_mtime = 2016-12-28T09:16:55 + 0200.816363098、
 st_ctime = 2016-12-28T09:16:55 + 0200.816363098})= 0 
-データがコピーされます
 open( "foo"、O_RDONLY | O_NOFOLLOW)= 3 
 open( "bar"、O_WRONLY | O_TRUNC)= 4 
 read(3、 "test\n"、131072)= 5 
 write(4、 "test\n"、5)= 5 
 read(3、 ""、131072)= 0 
-修正時間がコピーされます
 utimensat(4、NULL、[{tv_sec = 1482909419、tv_nsec = 879714332}、
 {tv_sec = 1482909415、tv_nsec = 816363098}]、0) = 0 
-所有権がコピーされます( 'Sudo [strace] cp'を使用した場合のみ)
 fc hown(4、1000、1000)= 0 
-拡張属性がコピーされます(xdg.Origin.urlはブラウザーによって設定されます、wget)
 flistxattr(3、NULL、0)= 0 
 flistxattr(3、 "user.xdg.Origin.url\0"、20)= 20 
 fgetxattr(3、 "user.xdg.Origin.url"、 "https:// superuser。 com/"、22)= 22 
 fsetxattr(4、" user.xdg.Origin.url "、" https://superuser.com/ "、22、0)= 0 
- -POSIX ACLが存在しないため、基本的なACLはst_mode 
から構築されます-(この場合、単純なfchmod()も機能します)
 fgetxattr(3、 "system.posix_acl_access "、0x7ffc87a50be0、132)= -1 ENODATA(使用可能なデータなし)
 fsetxattr(4、" system.posix_acl_access "、"\2\0\0\0\1\0\6\0\377\377\377\377\4\0\4\0\377\377\377\377\0\4\0\377\377\377\377 "、28、0)= 0 
閉じる( 4)= 0 
閉じる(3)= 0 
…
42
user1686

一般に、メタデータが格納されているファイルシステムごとに異なります。ファイルシステムのext2ファミリーでは、言及したメタデータ(所有者、グループ、権限、時間)は inode に保存されます。 iノードは、ファイルがディスク上で占有しているブロックも格納(へのポインタ)します。 iノードはファイル名を保存しません。

このデータには、statシステムコール(man 2 stat)を使用してアクセスし、statツールを使用して印刷できます(man stat)。 inodeフィールドの詳細な説明は、カーネルソースのlinux/include/linux/fs.hにあります。

別の場所に保存されている他の種類のメタデータ(例 ACL権限 )があります。

ファイルをコピーしても、デフォルトではメタデータはコピーされません。代わりに、デフォルトのメタデータ値を持つ新しいファイルが作成されます。 cpで古いメタデータを読み取り、それに応じて新しいメタデータを変更することにより、cpにメタデータもコピーするように指示するstat-p--preserve)にはさまざまなオプションがあります。

11
dirkt

ファイルシステムに応じて、領域は(半)静的または動的に予約され、権限、サイズ、その他(場合によってはファイル名も)などのメタデータを保持します。

Unixでは、メタデータはinodeに格納され、ファイルが存在するデータ領域を制御します( ファイル名と関連するiノード番号はディレクトリエントリに格納されます )。

一部のファイルシステムでは、ディレクトリエントリは他のファイルと同様ですが、表示されません。 FATとFAT32はそのようなファイルシステムです(ただし、FATのルートディレクトリは「特別」です)。ファイルを作成するときは、ファイルが存在するフォルダを記述するエントリをファイルに追加/編集します。各エントリは、ファイルサイズ、名前、日付などを格納するのに十分な大きさです(複数のエントリを占める長い名前。32バイトのデフォルトのエントリサイズは、古い8 + 3文字形式で単一の名前を保持できます。これらすべて、もちろん、私の記憶が働いていると仮定して)。 Extシステムも同様ですが、ディレクトリエントリのサイズは動的に変更され、名前とiノードポインタのみが保持されます。他のすべての情報はiノードにあります。この方法では、2つのエントリが同じファイルを指す可能性があり、重複ファイルの管理に役立ちます。

一部のファイルシステムでは、メタデータに加えて少量のデータを保持するのに十分な大きさのiノードがあるため、ファイルがそこに収まる場合でも、余分なディスク領域を占有しません。 45バイトのファイルを作成しても、ディスクの空き容量はまったく変わりません。これらのバイトは保存されますinside iノード。私はext *ファミリーがこれをサポートしていると思います(NTFSも同様です)。これは、非常に小さなファイルを多数管理するのに役立ちます。

さらに他のファイルシステムでは、これらの追加の属性を格納する、メインのファイルシステムに沿った「ファントム」ファイルシステムに相当するものがあります。 ファイル情報だけでなく、場合によってはファイルアイコン も同様です。

一部のシステムには両方があります。NTFSには、inodeのような方法で機能する完全なディレクトリメタデータがあり、 代替データストリーム を作成する可能性があります。 「メイン」ファイル内のすべて。

4
LSerni