SlideShare une entreprise Scribd logo
1  sur  48
Télécharger pour lire hors ligne
ファイルシステム(2)
2014/07/27
Yoshihiro YUNOMAE
1
今回のメイン
• extentに管理されている物理ブロックの取得
• 初期化・未初期化
• extentの分割
• extentの追加
• extentがぎっしり詰まっているところに
extentを追加したらどうなる?
2
extentの復習
(http://www.slideshare.net/
YoshihiroYunomae/f-36905134)
ext4_map_blocks()!
-> ext4_ext_map_blocks() // extent用!
-> ext4_ext_handle_unwritten_extents()!
-> ext4_ext_convert_to_initialized() !
-> ext4_split_extent()!
-> ext4_split_extent_at()!
-> ext4_ext_insert_extent()!
-> ext4_create_new_leaf()
4
ext4_map_blocks()
• ext4用のlblockからpblockを取得する関数
• pblockの取得のことをmapという
• map中はi_data_semのwrite lockがかかる
• i_dataがこの操作中に変わることがあるため
i_data_sem
wlock
extentにおけるmap
• 論理ブロックは1つのextentに管理される範囲内か
• 2つ以上にまたがっていたら隣のextentも気にしなければならない
• 簡単のため、またがった状況は考えない
• 論理ブロックは初期化されているか
• 1つのextentで管理される論理ブロックは、               
全て初期化さてれいる or 全く初期化されていないのどちらか
• 周囲の論理ブロックは初期化されているか
• 前後の論理ブロックとマージ出来るならマージ
• extentを追加しようと思ったときに、そのブロック内に空きがあるか
5
lblk
1 eof_blockextent Nの管理領域
mapped blocks initialized blocks uninitialized blocks
extentの初期化済・未初期化
• 正確にはwritten/unwrittenが正しい
• initialized/uninitializedを使わないようにしようという動きもある
(http://www.spinics.net/lists/linux-ext4/msg42877.html)
• ここではwritten: 初期化済, unwritten: 未初期化 という意味
• ext4_extent構造体extのee_len(16bit)のMSBがunwritten(未初期化)フラグ
• EXT_INIT_MAX_LEN = (1UL << 15)
6
static inline int ext4_ext_is_unwritten(struct ext4_extent *ext)
{
return (le16_to_cpu(ext->ee_len) > EXT_INIT_MAX_LEN);
}
static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
{
return (le16_to_cpu(ext->ee_len) <= EXT_INIT_MAX_LEN ?
le16_to_cpu(ext->ee_len) :
(le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
}
ext4_ext_map_blocks()
• extent用のmapするブロックを取得する関数
• extentでないときはext4_ind_map_blocks()
• mapするブロックが複数にまたがっていないとき、ブロックが初期化済か 
未初期化かで処理がわかれる。
• 初期化済 & 未初期化に変更: ext4_ext_convert_initialized_extent()
• fallocate(2)でzero埋めするとき(FALLOC_FL_ZERO_RANGE)に使用
• 初期化済: そのままそのブロックを使用
• 未初期化: ext4_ext_handle_unwritten_extents()
• ここでは未初期化の場合を考える
7
8
ext4_map_blocks()!
-> ext4_ext_map_blocks() // extent用!
-> ext4_ext_handle_unwritten_extents()!
-> ext4_ext_convert_to_initialized() !
-> ext4_split_extent()!
-> ext4_split_extent_at()!
-> ext4_ext_insert_extent()!
-> ext4_create_new_leaf()!
! ! ! ! ! ! ! -> ext4_ext_split()!
! ! ! ! ! ! ! -> ext4_ext_grow_indepth()
ext4_ext_handle_unwritten_extents()
• 以下の条件を満たしたときに、この関数を実行
• あるextentsで管理している論理ブロック内に、mapしようとしている 
論理ブロックが存在(またがっていない)
• そのextentsで管理している論理ブロックは初期化されていない
• ext4_map_blocks()で使われるフラグによって様々な関数に分岐し、実際に
mapするブロック数(allocated)を取得
• ここではbuffered read/writeを想定
• ext4_ext_convert_to_initialized()を実行して、その結果をallocatedとして
返す
• et4_ext_convert_to_initialized()の結果によっては、要求したブロック数に
対して多くアロケーションする場合があり(前後のextentとマージした場
合など)、その場合は要求したブロック数に修正する
9
ext4_ext_convert_to_initialized()
• ここから先は、初期化されない論理ブロックと、初期化される論理ブロック
(mapする論理ブロック)を分ける作業
• 可能であれば前後のextentとマージしてしまう
• extentを2つあるいは3つにsplit
• 今からmapする論理ブロックがextentのどの位置にあるか、また前後の論理
ブロックの状態(初期化済か未初期化)で、マージするか分裂するか決定
!
• m_lblk: mapする最初の論理ブロック(mapped logical block)
• map_len: mapする論理ブロック数
• ee_block: extentの最初の論理ブロック
• ee_len: extentの使用論理ブロック数
10
ext4_ext_convert_to_initialized()
• ここから先は、初期化されない論理ブロックと、初期化される倫理ブロック
(mapする論理ブロック)を分ける作業
• 可能であれば前後のextentとマージしてしまう!
• extentを2つあるいは3つにsplit
• 今からmapする論理ブロックがextentのどの位置にあるか、また前後の論理
ブロックの状態(初期化済か未初期化)で、マージするか分裂するか決定
!
• m_lblk: mapする最初の論理ブロック(mapped logical block)
• map_len: mapする論理ブロック数
• ee_block: extentの最初の論理ブロック
• ee_len: extentの使用論理ブロック数
11
ext4_ext_convert_to_initialized()
• 前方のextentとマージする条件
• L0: extentの最初からmap
• L1: extentの範囲内(mal_len >= ee_lenはextentの削除を意味)
• L2: 前方にextentが存在
• C1: 前方のextentが初期化済
• C2, C3: 前方のextetのブロックと論理的・物理的に連続
• C4: マージした後もextentの最大サイズを超えない
12
if ((map->m_lblk == ee_block) && /*L0*/
(map_len < ee_len) && /*L1*/
(ex > EXT_FIRST_EXTENT(eh))) { /*L2*/
…
if ((!ext4_ext_is_unwritten(abut_ex)) && /*C1*/
((prev_lblk + prev_len) == ee_block) && /*C2*/
((prev_pblk + prev_len) == ee_pblk) && /*C3*/
(prev_len < (EXT_INIT_MAX_LEN - map_len))) { /*C4*/
ext4_ext_convert_to_initialized()
• 後方のextentとマージする条件
• L0: extentの最後までmap
• L1: extentの範囲内(mal_len >= ee_lenはextentの削除を意味)
• L2: 後方にextentが存在
• C1: 後方のextentが初期化済
• C2, C3: 後方のextetのブロックと論理的・物理的に連続
• C4: マージした後もextentの最大サイズを超えない
13
} else if (((map->m_lblk + map_len) == (ee_block + ee_len)) && /*L0*/
(map_len < ee_len) && /*L1*/
ex < EXT_LAST_EXTENT(eh)) { /*L2*/
…
if ((!ext4_ext_is_unwritten(abut_ex)) && /*C1*/
((map->m_lblk + map_len) == next_lblk) && /*C2*/
((ee_pblk + ee_len) == next_pblk) && /*C3*/
(next_len < (EXT_INIT_MAX_LEN - map_len))) { /*C4*/
ext4_ext_convert_to_initialized()
• ee_len(extentの長さ) <= ゼロ初期化長の場合、そのextent全体をゼロ初期化
!
!
• s_extent_max_zeroout_kb: デフォルト32
• extent_max_zeroout_kbというsysfsファイルが用意されている
• /sys/fs/ext4/sda1/extent_max_zeroout_kb
!
• 周囲とマージ出来る場合はマージする
• ext4_ext_try_to_merge()
14
max_zeroout = sbi->s_extent_max_zeroout_kb >>
(inode->i_sb->s_blocksize_bits - 10);
マージ処理
• マージのための条件 ext4_can_extents_be_merged()より
• 前後のextentが両方とも初期化済あるいは未初期化であること
• 前のextentの論理ブロックが後のextentの論理ブロックとつながること
• 前後のextentの論理ブロックの長さの合計がextentの管理最大数を超えな
いこと
• 前のextentの物理ブロックが後のextentの論理ブロックとつながること
15
マージ処理
16
static void ext4_ext_try_to_merge()
{
…
int merge_done = 0;
…
if (ex > EXT_FIRST_EXTENT(eh))
/* 左側のextentとマージ */
merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1);
!
if (!merge_done)
/* 右側のextentとマージ */
(void) ext4_ext_try_to_merge_right(inode, path, ex);
!
/* inode->i_dataの中に収められるなら収める */
ext4_ext_try_to_merge_up(handle, inode, path);
}
マージ処理
17
static int ext4_ext_try_to_merge_right() {
…
int merge_done = 0;
…
while (ex < EXT_LAST_EXTENT(eh)) {
if (!ext4_can_extents_be_merged(inode, ex, ex + 1))
break;
…
ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)
+ ext4_ext_get_actual_len(ex + 1));
…
if (ex + 1 < EXT_LAST_EXTENT(eh)) {
…
memmove(ex + 1, ex + 2, len);
}
le16_add_cpu(&eh->eh_entries, -1);
merge_done = 1;
…
}
return merge_done;
}
ext4_ext_convert_to_initialized()
• ここから先は、初期化されない論理ブロックと、初期化される倫理ブロック
(今からmapする論理ブロック)を分ける作業
• 可能であれば前後のextentとマージしてしまう
• extentを2つあるいは3つにsplit!
• 今からmapする論理ブロックがextentのどの位置にあるか、また前後の論理
ブロックの状態(初期化済か未初期化)で、マージするか分裂するか決定
!
• m_lblk: mapする最初の論理ブロック(mapped logical block)
• map_len: mapする論理ブロック数
• ee_block: extentの最初の論理ブロック
• ee_len: extentの使用論理ブロック数
18
ext4_ext_convert_to_initialized()
19
• ここまで来たということは、ee_len > max_zeroout
• splitには4つのパターンが存在(ここでは4パターンにするだけ)
1. 3つに分かれるパターン(真ん中に書き込まれる論理ブロックが存在)
2. 2つに分かれ、前半部分がmax_zerooutより小さいなら最初から0初期化
3. 2つに分かれ、後半部分がmax_zerooutより小さいなら最後まで0初期化
4. 2つに分かれるが初期化されない(両方ともmax_zerooutより大きい)
mapped blocks
max_zeroout
ee_len
1 2
43
20
ext4_map_blocks()!
-> ext4_ext_map_blocks() // extent用!
-> ext4_ext_handle_unwritten_extents()!
-> ext4_ext_convert_to_initialized() !
-> ext4_split_extent()!
-> ext4_split_extent_at()!
-> ext4_ext_insert_extent()!
-> ext4_create_new_leaf()!
! ! ! ! ! ! ! -> ext4_ext_split()!
! ! ! ! ! ! ! -> ext4_ext_grow_indepth()
ext4_split_extent()
• extent全体をsplitする関数
• 実際にsplitするのはext4_split_extent_at()
21
// mapped blocksがextent内 P.19 1, 2の右側
if (map->m_lblk + map->m_len < ee_block + ee_len) {
…
flags1 = flags | EXT4_GET_BLOCKS_PRE_IO; /* 後で出てくる */
…
err = ext4_split_extent_at(handle, inode, path,
map->m_lblk + map->m_len, split_flag1, flags1);
…
// 分岐しているが実際は全パターンで通過 p.19, 1-4の左側
if (map->m_lblk >= ee_block) {
…
err = ext4_split_extent_at(handle, inode, path,
map->m_lblk, split_flag1, flags);
ext4_split_extent_at()
• あるextentをsplitする関数
• P.19の2の左側のときはsplitする必要がないので前方のextentとマージ出
来るならマージしてしまう
• それ意外のときはsplitする右側部分をnewexと定義し、
ext4_ext_store_pblock()を実行
22
ext4_split_extent_at()
23
static int ext4_split_extent_at(…, ext4_lblk_t split,…)
{
…
struct ext4_extent newex;
struct ext4_extent *ex2 = NULL;
…
if (split == ee_block) { // P.19 2の左側だったら・・・
…
ext4_ext_try_to_merge(handle, inode, path, ex);
…
goto out;
}
…
ex2 = &newex;
ex2->ee_block = cpu_to_le32(split);
ex2->ee_len = cpu_to_le16(ee_len - (split - ee_block));
ext4_ext_store_pblock(ex2, newblock);
…
err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
ext4_map_blocks()!
-> ext4_ext_map_blocks() // extent用!
-> ext4_ext_handle_unwritten_extents()!
-> ext4_ext_convert_to_initialized() !
-> ext4_split_extent()!
-> ext4_split_extent_at()!
-> ext4_ext_insert_extent()!
-> ext4_create_new_leaf()!
! ! ! ! ! ! ! -> ext4_ext_split()!
! ! ! ! ! ! ! -> ext4_ext_grow_indepth()
24
ext4_ext_insert_extent()
• 新しいextentを追加する関数
• 前後のextentとマージ出来るならマージしてしまう
• もしマージ出来ないなら、今あるdepthにextentを追加するための空きがあ
るかチェック
• 空きがあったら新しいextentを作成する
• 空きが無かったらext4_create_new_leaf()を実行し、空きスペースを作る
• 空きスペースが出来たら、新しいextentを作成する
if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max))
/* 今のdepthに空きがある */
goto has_space;
…
/* 今のdepthに空きが無い */
err = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags,
path, newext);
…
has_space:
/* 後で説明 */
ext4_create_new_leaf()
• 新しいextentを割り込んで挿入するために、leafに空きを作る関数
• ext4_ext_find_extent()から取得したpath配列から、各深さに対して空のindex
を探し出す
• 出来るだけ深いところから(leafから)indexの空きを探し出す
!
!
!
!
!
!
!
• もし空のindexがあった場合、ext4_ext_split()でindexを追加する
• もし全ての深さに空のindexが無かった場合、ext4_ext_grow_index()で   
1段深くする
• 結果空きのindexが出来るのでext4_ext_split()でindexを追加する
26
i = depth = ext_depth(inode);
curp = path + depth; // 最初はleafから
// eh_entries < eh_max ?
while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {
i--;
curp--;
}
ext4_create_new_leaf()
27
static int ext4_ext_create_new_leaf()!
{!
…!
repeat:!
! // indexの空きを検索(前ページ)!
…!
if (EXT_HAS_FREE_INDEX(curp)) {!
! // 空き領域にindexを追加!
err = ext4_ext_split(handle, inode, mb_flags, path, newext, i);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
} else {!
// 1段深くする!
err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
/*!
* only first (depth 0 -> 1) produces free space;!
* in all other cases we have to split the grown tree!
*/!
depth = ext_depth(inode);!
if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) {!
/* now we need to split */!
goto repeat;!
}!
}!
…!
ext4_create_new_leaf()
28
static int ext4_ext_create_new_leaf()!
{!
…!
repeat:!
! // indexの空きを検索(前ページ)!
…!
if (EXT_HAS_FREE_INDEX(curp)) {!
! // 空き領域にindexを追加!
err = ext4_ext_split(handle, inode, mb_flags, path, newext, i);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
} else {!
// 1段深くする!
err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
/*!
* only first (depth 0 -> 1) produces free space;!
* in all other cases we have to split the grown tree!
*/!
depth = ext_depth(inode);!
if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) {!
/* now we need to split */!
goto repeat;!
}!
}!
…!
ext4_ext_split()
29
hdr
index
index
empty
extent
extent
depth=0
(i_data) depth=1 depth=at
… … …
…
depth
…
path[1].p_idx path[depth].p_ext
ここに
新しいextentを加えたい
ext4_ext_split()
extent
extent
…
depth
最も深いところの
目的のleaf以下の長さを
はかって・・・
m
30
ext4_ext_split()
31
extent
extent
…
depth
eh_entry=m
newblock
…
上書きされないように
新しいブロックに待避
memmove m
m
ext4_ext_split()
32
eh_entry - m
extent
extent
empty
…
depth
eh_entry=m
newblock
…
上書きされないように
新しいブロックに待避
m
ext4_ext_split()
33
extent
extent
empty
…
depth
newblock0
…
depth - 1
…
newblock1
…
newblock0用
memmove
空きindexのある
深さの前まで続ける
ext4_ext_insert_index()
(ext4_ext_split()の延長)
34
挿入したいextentの
論理ブロックはei_blockの前?
eh_entry++
…
newblockへ
eh_entry++
…
newblockへ
前 後
empty
depth=at
…
or
memmove
35
eh_entry++
…
newblockNへ
depth=at depth-1
…
at+1
…
extent
extent
…
depth
…
ext4_ext_split()の結果1
36
eh_entry++
newblockNへ
depth=at
depth
(newblock0)
…
depth - 1
(newblock1)
…
newblock0用
…
at+1
(newblockN)
…
at+2用
ext4_ext_split()の結果2
… ………
ext4_create_new_leaf()
37
static int ext4_ext_create_new_leaf()!
{!
…!
repeat:!
! // indexの空きを検索(前ページ)!
…!
if (EXT_HAS_FREE_INDEX(curp)) {!
! // 空き領域にindexを追加!
err = ext4_ext_split(handle, inode, mb_flags, path, newext, i);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
} else {!
// 1段深くする!
err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
/*!
* only first (depth 0 -> 1) produces free space;!
* in all other cases we have to split the grown tree!
*/!
depth = ext_depth(inode);!
if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) {!
/* now we need to split */!
goto repeat;!
}!
}!
…!
ext4_ext_grow_indepth()
38
hdr
index
index
extent
extent
depth=0
(i_data) depth=1 depth=k
… … …
…
depth
…
全て埋まっているので、
新しく深くしなければならない
ext4_ext_grow_indepth()
39
hdr
index
index
depth=0
(i_data) newblock
…
hdr
memmove
eh_maxの更新
ext4_ext_grow_indepth()
40
hdr
newblockへ
depth=0
(i_data)
depth=0のヘッダの更新
eh_entry=1
eh_depth++
新しい空きが出来た
-> ext4_ext_split()を実行
※indexが元々無い場合、
これで終了
newblock
…
hdr
ext4_create_new_leaf()
41
static int ext4_ext_create_new_leaf()!
{!
…!
repeat:!
! // indexの空きを検索(前ページ)!
…!
if (EXT_HAS_FREE_INDEX(curp)) {!
! // 空き領域にindexを追加!
err = ext4_ext_split(handle, inode, mb_flags, path, newext, i);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
} else {!
// 1段深くする!
err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext);!
…! ! ! ! // ext4_ext_find_extent()を使って配列pathの更新!
/*!
* only first (depth 0 -> 1) produces free space;!
* in all other cases we have to split the grown tree!
*/!
depth = ext_depth(inode);!
if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) {!
/* now we need to split */!
goto repeat;!
}!
}!
…!
やっとextentに空きが
出来た・・・
ext4_ext_insert_extent() {
…
if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max))
/* 今のdepthに空きがある */
goto has_space;
…
/* 今のdepthに空きが無い */
err = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags,
path, newext);
…
has_space:
/* 後で説明 */
43
ext4_ext_insert_extent()
extent
extent
…
depth
前に挿入する場合
(後ろ全部をmemmove)
後に挿入する場合
(後ろ全部をmemmove)
44
ext4_ext_insert_extent()
eh_entries++
extent
extent
newext
…
depth
新しいextentを追加出来たので
以後はnewextを利用
ext4の積み残し(適当な分類)
• ラスボス級(確実に1回以上かかる)
• ジャーナリング(jbd/jbd2)
• 中ボス級(1回で終わるかも)
• マウントオプション
• extend status tree
• fallocate(2)
• 一般級(複数個まとめて出来る)
• delayed / multiblock / persistent allocation
• inline data / xattr
• その他
• big allocation時のsmall fileの対策?
• ext4のfsckが高速化したのはなぜ?
• ext4_inode構造体の更新頻度は?
45
Appendix1: ext4_ext_find_extent()
• 目的の論理ブロックを管理している、各深さのindex(tree)/extent(leaf)を
バイナリサーチで探し出す関数
• ext4_ext_path構造体の深さ分の長さを持った配列pathを更新
• p_block: index/extentのある物理ブロック
• p_depth: 管理している深さ(0であればextent)
• p_ext: 目的のextentのポインタ(p_depth==0のときのみ存在)
• p_idx: 目的のextentを管理しているある深さのindexへのポインタ
(p_depth>0)
• p_hdr: ある深さのheaderへのポインタ
• p_bh: index/extentのある物理ブロックのバッファヘッダへのポインタ
• pathの配列順所は深さと逆
• path[max_depth].p_depth == 0
• path[0].p_depth == max_depth
46
Appendix2: i_size以上の管理
• max_zerooutを取得する前に、以下のようなソースあり。
!
!
• EXT4_EXT_MAY_ZEROOUT: もしENOSPCでsplitに失敗したらそのextentを初
期化するフラグ
• i_size以上の領域に初期化済のブロックがあると、fsckで不正なinode sizeだと
されてしまうため、eof_blockより大きいextentにはENOSPCでsplit出来なく
ても初期化しない
• 一昔前(4年前)ではinode->i_size以上のブロック領域をextentで管理出来た
• EXT4_INODE_EOFBLOCKS (inode用), EXT4_EOFBLOCKS_FL(user空間用)
• しかしこの機能はもはや使われていない
• カーネル内ではEXT4_INODE_EOFBLOCKSをチェックして特別な処理を
する機能は無い
• fsckもEXT4_EOFBLOCKS_FLをremove
47
split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
buffered writeのprocdedure
ext4_write_begin()!
-> _ext4_get_block() // EXT4_GET_BLOCKS_CREATE(buffered write)!
-> ext4_map_blocks()!
-> ext4_ext_map_blocks()// ext4_es_lookup_extent()×!
-> ext4_ext_handle_unwritten_extents() // m_lblkがextentの管理内!
                       & extentはunwritten!
! ! ! ! ! ! ! add EXT4_GET_BLOCKS_METADATA_NOFAIL!
-> ext4_ext_convert_to_initialized() !
-> ext4_split_extent() // mapがextentの管理の途中から開始!
! ! ! ! ! ! ! ! ! mapがextentと同一長さでない!
! ! ! ! ! ! ! & ee_len * blocksize > extent_max_zeroout_kb!
(extent_max_zeroout_kbはデフォルト32、sysfsでも変更可能)!
-> ext4_split_extent_at()!
-> ext4_ext_insert_extent()!
-> ext4_create_new_leaf()
48

Contenu connexe

Tendances

[Basic 8] プロセスとスレッド / 入出力 / シェル
[Basic 8] プロセスとスレッド / 入出力 / シェル[Basic 8] プロセスとスレッド / 入出力 / シェル
[Basic 8] プロセスとスレッド / 入出力 / シェルYuto Takei
 
Page frame management
Page frame managementPage frame management
Page frame managementsiburu
 
[Basic 9] 並列処理 / 排他制御
[Basic 9] 並列処理 / 排他制御[Basic 9] 並列処理 / 排他制御
[Basic 9] 並列処理 / 排他制御Yuto Takei
 
10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤ10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤTakashi Hoshino
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門sandai
 
あるキャッシュメモリの話
あるキャッシュメモリの話あるキャッシュメモリの話
あるキャッシュメモリの話nullnilaki
 
Basic of virtual memory of Linux
Basic of virtual memory of LinuxBasic of virtual memory of Linux
Basic of virtual memory of LinuxTetsuyuki Kobayashi
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門sandai
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門sandai
 
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~nullnilaki
 
core dumpでcode golf
core dumpでcode golfcore dumpでcode golf
core dumpでcode golfNomura Yusuke
 
ロボットシステム学2015年第5回
ロボットシステム学2015年第5回ロボットシステム学2015年第5回
ロボットシステム学2015年第5回Ryuichi Ueda
 
20181110 fok2018-pg-extension
20181110 fok2018-pg-extension20181110 fok2018-pg-extension
20181110 fok2018-pg-extensionToshi Harada
 
【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門 【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門 sandai
 
【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門 【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門 sandai
 
フレッシャーズのためのパケット解析入門
フレッシャーズのためのパケット解析入門フレッシャーズのためのパケット解析入門
フレッシャーズのためのパケット解析入門彰 村地
 

Tendances (20)

[Basic 8] プロセスとスレッド / 入出力 / シェル
[Basic 8] プロセスとスレッド / 入出力 / シェル[Basic 8] プロセスとスレッド / 入出力 / シェル
[Basic 8] プロセスとスレッド / 入出力 / シェル
 
14(haifu)
14(haifu)14(haifu)
14(haifu)
 
Page frame management
Page frame managementPage frame management
Page frame management
 
Slide
SlideSlide
Slide
 
[Basic 9] 並列処理 / 排他制御
[Basic 9] 並列処理 / 排他制御[Basic 9] 並列処理 / 排他制御
[Basic 9] 並列処理 / 排他制御
 
10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤ10分で分かるLinuxブロックレイヤ
10分で分かるLinuxブロックレイヤ
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門
 
あるキャッシュメモリの話
あるキャッシュメモリの話あるキャッシュメモリの話
あるキャッシュメモリの話
 
Basic of virtual memory of Linux
Basic of virtual memory of LinuxBasic of virtual memory of Linux
Basic of virtual memory of Linux
 
Preseeding Debian
Preseeding DebianPreseeding Debian
Preseeding Debian
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門
 
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~オープンソース開発と、あるフレームバッファコンソールの話~名古屋応用編~
オープンソース開発と、 あるフレームバッファコンソールの話 ~名古屋応用編~
 
core dumpでcode golf
core dumpでcode golfcore dumpでcode golf
core dumpでcode golf
 
ロボットシステム学2015年第5回
ロボットシステム学2015年第5回ロボットシステム学2015年第5回
ロボットシステム学2015年第5回
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
20181110 fok2018-pg-extension
20181110 fok2018-pg-extension20181110 fok2018-pg-extension
20181110 fok2018-pg-extension
 
【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門 【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門
 
【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門 【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門
 
フレッシャーズのためのパケット解析入門
フレッシャーズのためのパケット解析入門フレッシャーズのためのパケット解析入門
フレッシャーズのためのパケット解析入門
 

Ext4 filesystem(2)