ジョニーがEMPTYファイルを作成するとします。と呼ばれfoobar.py
ます。ジョニーが実行を許可すると、実行しますchmod 755 foobar.py
。ファイルには、次のメタデータが含まれています。
-rw-r--r-- 1 johnny staff 0 Dec 27 22:53 foobar.py
そのすべてのメタデータはそのファイルのどこに保存されていますか?ファイルのサイズは0ですが、別のドライブに転送されるときにメタデータをどのように保持しますか?
ジョニーがEMPTYファイルを作成するとします。と呼ばれfoobar.py
ます。ジョニーが実行を許可すると、実行しますchmod 755 foobar.py
。ファイルには、次のメタデータが含まれています。
-rw-r--r-- 1 johnny staff 0 Dec 27 22:53 foobar.py
そのすべてのメタデータはそのファイルのどこに保存されていますか?ファイルのサイズは0ですが、別のドライブに転送されるときにメタデータをどのように保持しますか?
回答:
そのファイルには保存されません。ファイルシステムに保存され、すべてのパラメーターは手動で1つずつコピーされます(ただし、一部はまったくコピーできません)。
つまり、ほとんどのオペレーティングシステムには、「メタデータ付きファイルのコピー」呼び出しが実際にはありません。ファイルコピープログラムは、という名前の新しいファイルを作成し、foobar.py
0バイトのデータ全体をコピーし、utime()またはSetFileTime()を使用して、変更時刻を元の時刻と同じに見せます。同様に、chmod()を使用して新しく設定するか、POSIX ACL属性をコピーすることにより、ファイルのアクセス権を「コピー」します。
一部のメタデータはコピーされません。所有権を設定するにはルート権限が必要なので、他の人のファイルのコピーがあなたのものであり、ディスククォータを占有します。UNIXでは、ctime(属性変更時間)を手動で設定することはできません。btime(生年月日/作成時間)も通常はコピーされません。
比較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のみ) fchown(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 close(4)= 0 close(3)= 0 …
通常、メタデータが保存されるファイルシステムごとに異なります。ファイルシステムのext2ファミリーでは、あなたが言及したメタデータ(所有者、グループ、許可、時間)はinodeに保存されます。また、iノードは、ファイルがディスク上で占有するブロックを格納(ポインター)します。iノードはファイル名を保存しません。
このデータにアクセスするには、stat
システムコール(man 2 stat
)を使用し、stat
ツールを使用して印刷します(man stat
)。iノードフィールドの詳細な説明はlinux/include/linux/fs.h
、カーネルソースにあります。
別の場所に保存されている他の種類のメタデータ(ACL許可など)があります。
ファイルをコピーすると、デフォルトではメタデータはコピーされません。代わりに、デフォルトのメタデータ値を持つ新しいファイルが作成されます。cp
(-p
、--preserve
)にはさまざまなオプションがありcp
、古いメタデータを読み取り、stat
それに応じて新しいメタデータを変更することにより、メタデータもコピーするよう指示します。
ファイルシステムに応じて、領域は(半)静的または動的に予約され、アクセス許可、サイズなどのメタデータ(ファイル名も含む)を保持します。
Unixでは、メタデータはファイルが存在するデータ領域を制御するiノードに格納されます(ファイル名と関連するiノード番号はディレクトリエントリに格納されます)。
一部のファイルシステムでは、ディレクトリエントリは他のファイルと同様ですが、表示されないファイルです。FATとFAT32はそのようなファイルシステムです(FATのルートディレクトリは「特別」ですが)。ファイルを作成するとき、ファイルが存在するフォルダーを記述するエントリをファイルに追加/編集します。各エントリは、ファイルサイズ、名前、日付などを格納するのに十分な大きさです(複数のエントリを占める長い名前。32バイトのデフォルトエントリサイズは、古い8 + 3文字形式の単一の名前を保持できます。 、私の記憶が働いていると仮定します)。Extシステムも同様ですが、ディレクトリエントリのサイズは動的に変更され、名前とiノードポインタのみが保持されます。他のすべての情報はiノードにあります。この方法では、2つのエントリが同じファイルを指す場合があり、重複ファイルを管理するのに役立ちます。
一部のファイルシステムでは、iノードはメタデータに加えて少量のデータを保持するのに十分な大きさであるため、ファイルがそこに収まる場合、余分なディスク領域を占有しません。45バイトのファイルを作成しても、ディスクの空き容量はまったく変化しません。これらのバイトはiノード内に保存されます。ext *ファミリーがこれをサポートしている(そしてNTFSも)と思います。これにより、多数の非常に小さなファイルを管理できます。
さらに他のファイルシステムでは、これらの追加の属性を保存する、メインシステムに沿った「ファントム」ファイルシステムに相当するものがあります。ファイル情報だけでなく、アイコンもファイルする可能性があります。
一部のシステムには両方があります。NTFSには、inodeのように動作する完全なディレクトリメタデータがあり、「メイン」ファイルの内容を(明らかに)変更しない追加情報を保持する代替データストリームを作成できます。