Chapter 4 Files and Directories

ファイルの種類

sticky bit S_ISVTX

歴史

ファイルのtext部分 (=命令列)がメモリのスワップエリアに保存され、プログラムだと起動が早くなる。 スワップエリアに張り付くので sticky

ディレクトリに対するsticky bit

スティッキービットが設定されているディレクトリでは、書き出し権限を持つユーザで、以下の条件のいずれかを満たすならディレクトリ内のファイルの削除・名前変更をできる

inodes

ファイルに関するすべての情報は iノードにあるので、ディレクトリエントリにはファイル名とiノード番号(ino_t 型)しかない。

ln がファイルシステムを跨げないのは inodes のため

ディレクトリエントリ内のiノードは同じファイルシステム内のiノードを指す

ファイルシステムを変えずにファイル名を変える

動作確認

btrfs

クローンニング cloning

ファイルシステム上でみると、ハードリンクだと同じファイルの別名、ということ。 btrfs での cloning はディスクブロックを共有する独立したファイルとなる inodesが複数あるということ? cp --reflink が使えるようになっている

By cloning, the file system does not create a new link poiting to an existing inode; instead, it creates a new inode tha initially share the same disk blocks with the original file.

The actual data blocks are not duplicated; at the same time, due to the copy-on-write nature of Btrfs, modifications to any of cloned files are not visible to the original files and vice versa.

linkat

link は簡単なので、linkat について。 int linkat(int olddirfd, const char* oldpath, int newdirfd, const char* newpath, int flags);

man 2 linkat

If the pathname given in oldpath is relative, then it is interpreted relative to the directory reffered to by the file descriptor, olddirfd (rather than relative to the c.w.d. of the calling process, as is done by link() for a relative path name).

If oldpath is relative and olddirfd is special value AT_FDCWD, then oldpath is interpreted relative to the c.w.d. of the calling process.

If oldpath is absolute, then olddirfd is ignored.

The interpretation of newpath is as for oldpath, except that a relative pathname is interpreted relative to the directory referered to by the file descriptor newdirfd.

最後の部分は、newpath の解釈について、 newdirfd が参照するディレクトリに対して relative だというところ以外は oldpath と一緒。

  1. ファイルをクローズすると、カーネルは対象のファイルを開いているプロセス数を数える
  2. この個数が0になると、次にリンクカウントを検査する
  3. そのカウントが0なら削除する

ファイルの時刻

フィールド 意味 ls (1)のオプション
st_atim データへの最終アクセス時刻 read -u
st_mtim データの最終修正時刻 write デフォルト
st_ctim iノード状態の変更時刻 chmod,chown -c

ファイルシステム上では、ファイルデータとiノードは別に管理しているので、iノードの変更時刻もトラックする必要がある。 また、iノードアクセス時刻は管理しない(またaccessstat はどの時刻も変えない)。

ディレクトリエントリへの追加/変更

時刻の変更

#include <sys/stat.h>
int futimes(int fd, const struct timespec times[2]);
int utimensat(int dirfd, const char *path, const struct timespec times[2], int flags);

stuct timespec {
   time_t tv_sec;
   long   tv_nsec;
};
#include <sys/time.h>
int utimes(const char *pathname, const struct timeval times[2]);

struct timeval {
	long tv_sec;
	long tv_usec;
}

メモ: 仕様について

4.21 mkdir, mkdirat, rmdir

4.22 ディレクトリの読み取り

struct dirent {
    ino_t          d_ino;       /* Inode number */
    off_t          d_off;       /* Not an offset; see below */
    unsigned short d_reclen;    /* Length of this record (WARN: size in bytes!) */
    unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
    char           d_name[256]; /* Null-terminated filename */
};

The value returned in d_off is the same as would be returned by calling telldir(3) at the current position in the directory stream.

chdir/fchdir/getcwd