ãã®èšäºã§ã¯äœãèµ·ãããŸããïŒ
Academic Universityã® OSã³ãŒã¹ã®è³æã«åºã¥ããŠãLinuxã«ãŒãã«ã§ãã¡ã€ã«ã·ã¹ãã ãäœæããããšã«é¢ããäžé£ã®èšäºãç¶ããŸãã
ååã¯ãã³ã¢ã«ç²Ÿéããããã«å¿ èŠãªç°å¢ãèšå®ããŸããã 次ã«ãããŒãå¯èœãªã«ãŒãã«ã¢ãžã¥ãŒã«ãèŠãŠãç°¡åãªãHelloãWorldïŒããäœæããŸããã ãããŠæåŸã«ãã·ã³ãã«ã§åœ¹ã«ç«ããªããã¡ã€ã«ã·ã¹ãã ãäœæããŸããã ç¶è¡ããæéã§ãã
ãã®èšäºã®äž»ãªç®çã¯ããã¡ã€ã«ã·ã¹ãã ã«ãã£ã¹ã¯ããã®èªã¿åããæããããšã§ãã ãããŸã§ã®ãšããã圌女ã¯ãµãŒãã¹æ å ±ïŒã¹ãŒããŒãããã¯ããã³ã€ã³ããã¯ã¹ããŒãïŒã®ã¿ãèªã¿åããããããã䜿çšããããšã¯äŸç¶ãšããŠéåžžã«å°é£ã§ãã
ãªããããªã«å°ãªãã®ã§ããïŒ å®éããã®æçš¿ã§ã¯ããã¡ã€ã«ã·ã¹ãã ã®æ§é ãã€ãŸããã£ã¹ã¯ã«ä¿åããæ¹æ³ã決å®ããå¿ èŠããããŸãã ããã«ãSLABãRCUãªã©ã®èå³æ·±ãç¹ãããã€ããããŸãã ããã«ã¯ãã¹ãŠèª¬æãå¿ èŠã«ãªããŸã-ããããã®åèªãšå°ããªã³ãŒããªã®ã§ãæçš¿ã¯ãã§ã«èšå€§ãªéã«ãªããŸãã
éå±ãªã¹ã¿ãŒã
ãã¡ã€ã«ã·ã¹ãã ã¯ã·ã³ãã«ã§ããå¿ èŠããããŸãããããã£ãŠãåçŽã«ãã£ã¹ã¯ã«ä¿åãããŸãã
æåŸããå§ããŸãããïŒ
- ããŒã¿ãããã¯-æçšãªããŒã¿ã®ãããã¯ãã€ãŸããã¡ã€ã«ãšãã©ã«ããŒã®å 容;
- iããŒãã®ããŒãã«-ã€ã³ããã¯ã¹ããŒãã®ããŒãã«ã ã€ã³ããã¯ã¹ããŒãã®æ°ã¯ãã©ãŒãããäžã«æ±ºå®ãããé£ç¶ããäžé£ã®ãããã¯ã«æ ŒçŽãããŸãã
- 空ãiããŒã-ã¡ããã©1ãããã¯ãå æãã空ã/䜿çšäžã®ã€ã³ããã¯ã¹ããŒãã®ããããããã
- 空ããããã¯-空ã/å æãããã¯ã®ããããããã1ãããã¯ãå æããŸãã
- ã¹ãŒããŒãããã¯-æããã«ããã¡ã€ã«ã·ã¹ãã ã®ã¹ãŒããŒãããã¯ã ãããã¯ãµã€ãºãã€ã³ããã¯ã¹ããŒãããŒãã«ã®ãããã¯æ°ãã«ãŒããã©ã«ããŒã®ã€ã³ããã¯ã¹ããŒãçªå·ãæ ŒçŽããŸãã
å®éã«ã¯ãä»ã®ãã¡ã€ã«ã·ã¹ãã ã§ãåæ§ã®ãã£ã¹ã¯ã¬ã€ã¢ãŠãã䜿çšãããŠããŸãã ããšãã°ãext2 / 3ã®ãããã¯ã®ã°ã«ãŒãã¯åæ§ã®æ§é ãæã¡ãext2 / 3ã®ã¿ãè€æ°ã®ãã®ãããªã°ã«ãŒãã§æ©èœãã1ã€ã«å¶éããŸãã ãã®åœ¢åŒã¯æ代é ããšèŠãªãããŠãããæ°ãããã¡ã€ã«ã·ã¹ãã ã¯ãã®åœ¢åŒããé ãããã€ã€ãããŸãã ããšãã°ãbtrfsã¯ãextãã¡ããªã«æ¯ã¹ãŠããã€ãã®å©ç¹ãæäŸãããããèå³æ·±ãã¹ããŒã ã䜿çšããŸãã ããããçŸã«æ»ããŸãããã
ãããã¯/ã€ã³ããã¯ã¹ããŒãã®ã¹ãŒããŒãããã¯ãšããããããããã¡ã€ã«ã·ã¹ãã ã®æåã®3ãããã¯ãå æããã€ã³ããã¯ã¹ããŒãããŒãã«ãã©ãã ãå æããããå€æããŸããã äžè¬çã«ããã®å€ãä¿®æ£ããããšã¯æ£ãããããŸãã;ãã¡ã€ã«ã·ã¹ãã ã®äœ¿çšæ¹æ³ã«å€§ããäŸåããŸãã ããšãã°ãäž»ã«å€§ããªãã¡ã€ã«ãä¿åããå Žåããã£ã¹ã¯ã¹ããŒã¹ãããæ©ãã€ã³ããã¯ã¹ããŒãã䜿ãæããå¯èœæ§ã¯äœãããããã®ããŒãã«ãå°ããããããšã¯çã«ããªã£ãŠããŸãã äžæ¹ãå°ããªãã¡ã€ã«ã倧éã«ä¿åããå ŽåãããŒãã«ãå°ãããããšã空ããã£ã¹ã¯å®¹éãããæ©ãã€ã³ããã¯ã¹ããŒããäžè¶³ããå¯èœæ§ããããŸãã
ext2 / 3ãã¡ã€ã«ã·ã¹ãã çšã«ãã£ã¹ã¯ããã©ãŒãããããããã«äœ¿çšãããmke2fsãŠãŒãã£ãªãã£ã«ã¯ãã€ã³ããã¯ã¹ããŒããäœæãããã£ã¹ã¯å®¹éã瀺ã-iã¹ã€ããããããŸããã€ãŸãã-i 16384ãæå®ãããšã16 KBããšã«ã€ã³ããã¯ã¹ããŒãã«ãã£ãŠäœæãããŸãã æãåçŽãªãªãã·ã§ã³ã䜿çšããŸãã16KBã®ãã£ã¹ã¯ã¹ããŒã¹ããšã«ã€ã³ããã¯ã¹ããŒããäœæãããã®å€ãå€æŽããå¯èœæ§ã¯ãããŸããïŒå°ãªããšãçŸæç¹ã§ã¯ïŒã
èšåãã䟡å€ã®ããæåŸã®å ±éç¹ã¯ããããã¯ãµã€ãºã§ãã ãã¡ã€ã«ã·ã¹ãã ã¯ããŸããŸãªãµã€ãºã®ãããã¯ã§åäœããŸãã512ã1024ã2048ã4096ãã€ãã®ãããã¯ããµããŒãããŸã-ç°åžžãªããšã¯äœããããŸããã ããã¯ãããŒãžã«åãŸããããã¯ã䜿çšããæ¹ãç°¡åã ããã§ãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒããããã¯ãŸã£ããå¿ èŠãããŸãããããã«ããããã¯ãµã€ãºã倧ãããããšããã©ãŒãã³ã¹ãåäžããŸãã
äžè¬ã«ãåŸæ¥ã®ãã¡ã€ã«ã·ã¹ãã ã«é©åãªãããã¯ãµã€ãºãéžæããããšã¯éåžžã«èå³æ·±ããããã¯ã§ãã ããšãã°ãOSã«é¢ããæåãªæ¬ã§ã¯ ããããã¯ãµã€ãºã4 KBã®å Žåããã¡ã€ã«ã®60ã70ïŒ ã1ã€ã®ãããã¯ã«é 眮ããããšããæ å ±ãæäŸãããŠããŸãã 1ã€ã®ãããã¯ã«åãŸããã¡ã€ã«ãå€ãã»ã©ãæçåãå°ãªããªããèªã¿åãé床ãéããªããŸãããç¡é§ã«ãªãã¹ããŒã¹ãå¢ããŸãã ç§ãã¡ã®å Žåããšãããããããã¯ãµã€ãºã¯ãã¡ã€ã«ã·ã¹ãã ã®äž»ãªå¶éã§ãã4KBã®ãããã¯ãµã€ãºã§ã¯ã空ããããã¯ã®ããããããã¯128 MBã®ãã£ã¹ã¯ã¹ããŒã¹ããã«ããŒã§ããŸããã
ç·Žç¿ã«æ»ã
ããããã³ãŒããäœæããŸãã æãåçŽãªãã®ããå§ããŠã䜿çšããæ§é ããå§ããŸãããã
struct aufs_disk_super_block { __be32 dsb_magic; __be32 dsb_block_size; __be32 dsb_root_inode; __be32 dsb_inode_blocks; };
ã¹ãŒããŒãããã¯æ§é ã¯ã0ãããã¯ãã£ã¹ã¯ã®å é ã«ä¿åãããŸãã ããã¯ããžãã¯ãã³ããŒã§å§ãŸããŸããããã«ããã°ãaufsããã£ã¹ã¯ã«ä¿åãããŠããããšã確èªã§ããŸãïŒããã«ã€ããŠã¯åã«è¿°ã¹ãŸããïŒã
ããŸããŸãªãããã¯ãµã€ãºããµããŒãããããšãèãããšïŒãã ããç§ãã¡ã®åªåã¯å¿ èŠãããŸããïŒããã®ç¹å®ã®ãã¡ã€ã«ã·ã¹ãã ã§äœ¿çšãããŠãããµã€ãºãç¥ãå¿ èŠããããã¹ãŒããŒãããã¯ã¯ãã®æ å ±ãdsb_block_sizeãã£ãŒã«ãã«æ ŒçŽããŸãã
ããã«ãã€ã³ããã¯ã¹ããŒãã®ããŒãã«å ã®ãããã¯æ°ã¯dsb_inode_blocksãã£ãŒã«ãã«æ ŒçŽãããŸã-ãã®ããŒãã«ã®ãµã€ãºã¯ç°ãªãå¯èœæ§ãããããšã¯æ¢ã«è¿°ã¹ãŸããã
dsb_root_inodeãã£ãŒã«ãã«ã¯ãã«ãŒããã£ã¬ã¯ããªã®ã€ã³ããã¯ã¹ããŒãçªå·ãæ ŒçŽãããŸãã ãã¡ããããããä¿åããå¿ èŠã¯ãããŸãããåã«ã«ãŒãã«åºå®æ°ã䜿çšããããšãã§ããŸãããæ§é ã¯å®å šã«ç©ºã«ãªããããã«ãã£ãŠãã匷åºã«ãªããŸãã
ãã£ãŒã«ãã«ã¯åºå®ãµã€ãºã¿ã€ãã䜿çšãããããšã«æ³šæããŠãã ããã ããã¯ããã®æ§é ããçŸç¶ã®ãŸãŸããã£ã¹ã¯ã«æžã蟌ãããã§ãã ãã ãããµã€ãºãä¿®æ£ããã ãã§ã¯ååã§ã¯ãªãããã€ãé ãä¿®æ£ããå¿ èŠããããŸãã ååïŒ__be32ïŒã瀺ãããã«ã ããã°ãšã³ãã£ã¢ã³ã䜿çšããŸããããã¯ãããã¯ãŒã¯ãã€ããªãŒããŒã§ãã
ååãšããŠãã©ã®é åºã䜿çšãããã¯ç¹ã«éèŠã§ã¯ãããŸãããäž»ãªããšã¯ããããä¿®æ£ããããšã§ãã ãªãã«ãšã³ãã£ã¢ã³ã䜿çšãããã©ãããã©ãŒã ã¯ä»ã«ããããšããæèŠãããããã䜿çšããããšããå§ãããŸãããããžãã¹ã«æ»ããŸãããã
__be32åã¯ãå®éã«ã¯uint32_tã®å矩èªã§ããããã®ååã¯å€æ°ãããã°ãšã³ãã£ã¢ã³ïŒäžçš®ã®ããã¥ã¡ã³ããŒã·ã§ã³ã¡ãœããïŒã§ããŒã¿ãæ ŒçŽããããšã匷調ããŠããŸãã ã«ãŒãã«ã«ã¯ããªãã«ãšã³ãã£ã¢ã³çšã®åæ§ã®ã¿ã€ãããããŸãã
次ã«ããã¡ã€ã«ã·ã¹ãã ã®æãéèŠãªæ§é ã§ããã€ã³ããã¯ã¹ããŒããèŠãŠã¿ãŸãããã
struct aufs_disk_inode { __be32 di_first; __be32 di_blocks; __be32 di_size; __be32 di_gid; __be32 di_uid; __be32 di_mode; __be64 di_ctime; };
ã€ã³ããã¯ã¹ããŒãã¯ãäž»ã«ãã¡ã€ã«/ãã£ã¬ã¯ããªã®ãã£ã¹ã¯äžã®ä¿åå Žæã決å®ããŸãã ãã¡ã€ã«ã®ä¿åæ¹æ³ã¯éåžžã«å€æ§ã§ããå¯èœæ§ãããããããã¡ã€ã«ããšã«ããªãåçŽãªãšã¯ã¹ãã³ãã䜿çšããŸãã ç¯å²-ãã£ã¹ã¯ãããã¯ã®é£ç¶ããã·ãŒã±ã³ã¹ãã€ãŸããåãã¡ã€ã«/ãã£ã¬ã¯ããªã¯ãããã¯ã®é£ç¶ããã·ãŒã±ã³ã¹ã«æ ŒçŽãããŸãã di_firstãã£ãŒã«ããšdi_blocksãã£ãŒã«ãã«ã¯ããããããšã¯ã¹ãã³ãå ã®æåã®ãããã¯ãšãããã¯æ°ãæ ŒçŽãããŸãã
ããã§ããªãã¯èšããŸããããã®ãããªãã¡ã€ã«ã·ã¹ãã ã§ãã¡ã€ã«ã®æåŸã«ããŒã¿ãè¿œå ãããã£ã¬ã¯ããªã«ãšã³ããªãè¿œå ããæ¹æ³ã¯ïŒ å®éããã®ã¹ãã¬ãŒãžæ¹æ³ã§ãã¡ã€ã«/ãã£ã¬ã¯ããªã®ãµã€ãºãå€æŽããæäœã®æ¬æ Œçãªå®è£ ã¯é çã®çš®ã§ãïŒãã®ãããªå®è£ ã®æå¹æ§ã¯èšããŸã§ããããŸããïŒããããã£ãŠãã¬ã³ãŒãã®æ¬æ Œçãªå®è£ ã¯è¡ããŸããããããã«ã€ããŠã¯å¥ã®èšäºã§è©³ãã説æããŸãã
ãã ãããã®ãããªçµç¹ã«ã¯ããã€ãã®è¯å®çãªåŽé¢ããããŸã-ãã¡ã€ã«ã¯æçåãããŠããããããã¯é 次èªã¿åãã®é床ã«è¯ã圱é¿ãåãŒããŸãã ãããã£ãŠããã®ãããªæ§é ã¯ãèªã¿åãå°çšã®ãã¡ã€ã«ã·ã¹ãã ãããšãã°iso 9660 ïŒæ¢ã«ãã¡ã€ã«ã®æçåããµããŒãããŠããŸããïŒã§çŽ æŽããã䜿çšãå¯èœã§ãã
ãšã¯ã¹ãã³ãã¯ããªãããŒãªæ§é ã§ã¯ãªããã»ãšãã©æäŸãããªãããšã¯æããã§ããããã£ã¹ã¯ã«ãã¡ã€ã«ãæ ŒçŽããããã®å€å žçãªããªãŒæ§é ãšäžç·ã«ããããã¯æçåããããã¡ã€ã«ã·ã¹ãã ã«ãéåžžã«è¯ããªãã·ã§ã³ã§ããããšãããããŸãã
ã€ã³ããã¯ã¹ããŒãã¯ããã£ã¹ã¯äžã®å Žæã瀺ãã ãã§ãªããå®éã®ãã¡ã€ã«ãµã€ãºãdi_sizeãã£ãŒã«ãã«æ ŒçŽããŸãã ãããŠçå®ã¯ããã¡ã€ã«ãµã€ãºã¯ãããã¯ãµã€ãºã«æ£ç¢ºã«é©åããå¿ èŠã¯ãããŸããã
di_gidããã³di_uidãã£ãŒã«ãã¯ãã°ã«ãŒããšãŠãŒã¶ãŒã®èå¥åã§ãã ãã®ãããªæ å ±ããã¡ã€ã«ã·ã¹ãã ã«ä¿åããããšã¯å¿ ãããæå³ããããŸãã;ããããäŸãšããŠæ¿å ¥ããŸããã
Di_modeãã£ãŒã«ã-ãã¡ã€ã«ææè ã°ã«ãŒãããã¡ã€ã«ææè ãããã³ä»ã®ãã¹ãŠã®ãŠãŒã¶ãŒã®ã¢ã¯ã»ã¹æš©ãæ ŒçŽããŸãã ã°ã«ãŒããšææè ãä¿åãããããã¢ã¯ã»ã¹æš©ã¯ä¿æãããŸãã Di_modeã¯ãã€ã³ããã¯ã¹ããŒããèšè¿°ãããªããžã§ã¯ãã®ã¿ã€ããããšãã°ãªããžã§ã¯ãããã£ã¬ã¯ããªã§ããããã¡ã€ã«ã§ããããªã©ãæ ŒçŽããŸãã
æåŸã«ãdi_ctimeãã£ãŒã«ãã«ã¯ããã¡ã€ã«ãäœæãããæ¥ä»ãä¿æãããŸãã éåžžããã¡ã€ã«ã·ã¹ãã ã¯ãäœææ¥ãšãšãã«ãæåŸã®å€æŽã®æ¥ä»ãšãã¡ã€ã«ãžã®ã¢ã¯ã»ã¹ãä¿åããŸããããããã«æãå ããŸãã
ãã£ã¹ã¯ããã©ãŒããããã
ãã®ããããã¡ã€ã«ã·ã¹ãã ããã£ã¹ã¯ã«ä¿åããããã®åœ¢åŒã決å®ãããããã£ã¹ã¯ãæ£ãã圢åŒã«ãããŠãŒãã£ãªãã£ãäœæããŸãã Linuxã®ãã£ã¹ã¯ã¯åãªããã¡ã€ã«ã§ãïŒããã§ã¯ã æåãªUnixã®èšèšãœãªã¥ãŒã·ã§ã³ãæãåºããŠãã ããïŒã ãããã£ãŠããã£ã¹ã¯ã®ãã©ãŒãããã¯ãå¿ èŠãªããŒã¿ããã¡ã€ã«ã«æžã蟌ãã ãã§ãã ãããŠããã®å Žåã«å¿ èŠãªããŒã¿ã¯ãã¹ãŒããŒãããã¯ããããããããããã³ã«ãŒããã£ã¬ã¯ããªïŒãããŸã§ã®ãšãã空ã§ãïŒã§ãã
Linuxã«ãŒãã«ã«é¢ããèšäºãC ++ã«é¢ããèšäºã«ïŒç¹ã«åŸè ã«å¯ŸããLinusã®æ 床ã«ç §ãããŠïŒå€ããªãããã«ããããã«ãgithubã®ãœãŒã¹ãèªåã§æ±ãããšããå§ãããŸãã
- æ§æ-å°æ¥ã®ãã¡ã€ã«ã·ã¹ãã ã®æ§æïŒãããã¯ãµã€ãºãã€ã³ããã¯ã¹ããŒãã®ããŒãã«ãµã€ãºããããã¯æ°ãããã€ã¹ãã¡ã€ã«åïŒãæ ŒçŽããã¯ã©ã¹ã
- ãããã¯-1ã€ã®ãã£ã¹ã¯ãããã¯ãè¡šããŸãã ããŒã¿ã®æžã蟌ã¿ãšèªã¿åãã¯ãããã¯åäœã§è¡ãããŸãã
- BlocksCache-ãããã¯ãžã®ã¢ã¯ã»ã¹ãæäŸããŸãã
- iããŒã-ã€ã³ããã¯ã¹ããŒãã®ã©ãããŒã ãããã¯ããã®ã€ã³ããã¯ã¹ããŒãããŒã¿ã®æžã蟌ã¿ãšèªã¿åãããã€ããªãŒããŒå€æãé ããŸãã
- SuperBlock-ã¹ãŒããŒãããã¯ã®ã©ãããŒã Inodeã®å Žåã®ããã«ããããã¯ãžã®æžã蟌ã¿ãšèªã¿åããé ãããããããããåããã€ã³ããã¯ã¹ããŒããšãããã¯ãéžæããŸããã€ãŸããå®éã«ãã©ãŒãããããŸãã
ãã®ãŠãŒãã£ãªãã£ã§ã¯ã-sãŸãã¯--block_sizeããŒã䜿çšããŠãããã¯ãµã€ãºãå€æŽãã-bãŸãã¯--blocksããŒã䜿çšããŠãã¡ã€ã«ã·ã¹ãã ã«äœ¿çšããããããã¯æ°ãå€æŽã§ããŸãã
äžè¬ã«ããŠãŒãã£ãªãã£ã¯ãŸã£ããããªãããŒã§ã¯ãããŸããããå€ãã®å Žåãã³ãŒãã¯ãã®ãããªåçŽãªã¿ã¹ã¯ã«ã¯æŽç·ŽãããŠãããšèãããããããŸããã å®éã«ã¯ããŸãããã¡ã€ã«ã·ã¹ãã ã«ãã£ã¹ã¯ããèªã¿åãããã«æ瀺ãã次ã«æžã蟌ã¿ãéå§ããŸãã ãã ãããã©ã€ããŒã®åäœã確èªããã«ã¯ããã£ã¹ã¯ã«äœããæžã蟌ãå¿ èŠããããŸãã ãã®ãããåŸã§ãŠãŒãã£ãªãã£ã«ãã£ã¹ã¯ããã©ãŒããããããšãã«ãã¡ã€ã«/ãã£ã¬ã¯ããªãã€ã³ããŒãããæ©èœãè¿œå ããŸããããã¯éåžžã«åœ¹ç«ã¡ãŸãã
ãã¡ã€ã«ã·ã¹ãã ã«æ»ã
ããŠã³ããŒãå¯èœãªã¢ãžã¥ãŒã«ã«æ»ããŸãã ãã£ã¹ã¯ããã¹ãŒããŒãããã¯ãèªã¿åãããšããå§ããŸãã ããããã®åã«ãã¹ãŒããŒãããã¯ã®å¥ã®æ§é ãååŸããŸãããã
struct aufs_super_block { uint32_t asb_magic; uint32_t asb_inode_blocks; uint32_t asb_block_size; uint32_t asb_root_inode; uint32_t asb_inodes_in_block; };
ãã®æ§é ã¯ãã¡ã¢ãªå ã®ã¹ãŒããŒãããã¯ãè¡šããŸãã ã¢ã€ãã¢ã¯ç°¡åã§ãããã£ã¹ã¯ããaufs_disk_super_blockãèªã¿åãããã€ãé å€æãå®è¡ããããããçš®é¡ã®æçšãªããŒã¿ïŒãã®å Žåã¯asb_inodes_in_blockïŒãåæã«èšç®ããããšã«ãããaufs_super_blockã«å€æããŸãã äžè¬ã«ããã®æ§é ã¯ãã°ããŒãã«ãã¡ã€ã«ã·ã¹ãã å€æ°ã«ãšã£ãŠæé©ãªå Žæã§ãã
æåŸã®æçš¿ãæãåºããŠãã¹ãŒããŒãããã¯ãè¡šãããã®3ã€ã®æ§é ãæ¢ã«ãããŸãã
- super_block-ã«ãŒãã«ãæäŸããæ§é ã
- aufs_disk_super_block-ãã£ã¹ã¯ã«ä¿åãããæ§é ã
- aufs_super_blockã¯ãã¡ã¢ãªã«æ ŒçŽãããå¥ã®æ§é ã§ãã
2ã€ã®æ§é -ããã¯ç解ã§ããŸããããªã3çªç®ã®æ§é ãå¿ èŠãªã®ã§ããïŒ äºå®ãLinuxã¯ãã¡ã€ã«ã·ã¹ãã ã«ã€ããŠäœãèªèããŠããªããããsuper_blockïŒä»ã®Linuxã«ãŒãã«æ§é ã®ãããªiããŒããªã©ïŒã«å¿ èŠãªãã£ãŒã«ãããã¹ãŠå«ãŸããŠããªãå¯èœæ§ããããŸãã ãããã£ãŠãè¿œå ã®æ§é ãéå§ããããããæ žã®æ§é ã«æ¥ç¶ããå¿ èŠããããŸãã ããããæ¥ç¶ããæ¹æ³ã¯ïŒ
ã«ãŒãã«ã«ã¯ããã®ãããªé¢ä¿ãæŽçãã2ã€ã®äžè¬çãªæ¹æ³ããããŸãïŒããããæ§æãšç¶æ¿ãšåŒã³ãŸãããïŒã ã¹ãŒããŒãããã¯ã«ã¯ãã³ã³ããžã·ã§ã³ã䜿çšããŸãã ãã®ã¡ãœããã«ã¯ã«ãŒãã«ã®ãµããŒããå¿ èŠã§ã-super_blockæ§é å ã«èå³æ·±ããã£ãŒã«ãããããŸã ïŒ
struct super_block { ... void *s_fs_info; ... };
ãã®ãã£ãŒã«ãã§ã¯ãä»»æã®ããŒã¿ãžã®ãã€ã³ã¿ãŒãä¿åã§ããŸããå®éã«ã¯ãaufs_super_blockãžã®ãã€ã³ã¿ãŒãä¿åããŸãã ãŸããsuper_blockæ§é äœã«ã¢ã¯ã»ã¹ã§ããå Žæã§ããã°ãaufs_super_blockæ§é äœã«ãã¢ã¯ã»ã¹ã§ããŸãã ããããã¯ããããã¯ãã¹ãŠã®æè©ã§ããç§ãã¡ã®ä»äºã¯ãã£ã¹ã¯ããã¹ãŒããŒãããã¯ãèªãããšã§ãã ãããè¡ãã«ã¯ãããã€ãã®é¢æ°ãäœæããŸãã
static struct aufs_super_block *aufs_super_block_read(struct super_block *sb) { struct aufs_super_block *asb = (struct aufs_super_block *)kzalloc(sizeof(struct aufs_super_block), GFP_NOFS); struct aufs_disk_super_block *dsb = NULL; struct buffer_head *bh = NULL; if (!asb) { pr_err("aufs cannot allocate super block\n"); return NULL; } bh = sb_bread(sb, 0); if (!bh) { pr_err("cannot read 0 block\n"); goto free_memory; } dsb = (struct aufs_disk_super_block *)bh->b_data; aufs_super_block_fill(asb, dsb); brelse(bh); if (asb->asb_magic != AUFS_MAGIC) { pr_err("wrong magic number %u\n", (unsigned)asb->asb_magic); goto free_memory; } return asb; free_memory: kfree(asb); return NULL; }
ãã®é¢æ°ãæåã«è¡ãããšã¯ãã¹ãŒããŒãããã¯æ§é ã«ã¡ã¢ãªãå²ãåœãŠãããšã§ãã ã«ãŒãã«ã«ã¡ã¢ãªãå²ãåœãŠãæ¹æ³ã¯ããªããããŸããã kzalloc ïŒããã³kmalloc ïŒãæãç°¡åã§ãã éåžžã®mallocã®ããã«æ©èœããè¿œå ã®ãã©ã°ã»ããã®è»¢éã®ã¿ãå¿ èŠã§ãã kzallocãškmallocã®éãã¯ãæåã®ã¡ã¢ãªãå²ãåœãŠãããã¡ã¢ãªããŒãã§åãããšããããšã§ãïŒããã¯åã«kmallocå ã«è¿œå ã®ãã©ã°ãæž¡ãããšã«ãªããŸãïŒã
ãã©ã°ã«ã€ããŠèšåããŸãããããªãã§ããïŒ äºå®ã¯ãã«ãŒãã«ã®ç°ãªãéšåãç°ãªãä¿èšŒãæºãããªããã°ãªããªããšããããšã§ãã ããšãã°ããããã¯ãŒã¯ãã±ããã®åŠçã®ã³ã³ããã¹ãã§ã¯ããããã¯ããããšã¯ã§ããŸãããDMAã䜿çšããã«ã¯ãç¹å¥ãªã¡ã¢ãªé åã«ã¡ã¢ãªãå²ãåœãŠãå¿ èŠããããŸã ã ã¡ã¢ãªå²ãåœãŠã¯ã©ãã§ã䜿çšããããããã調æŽãã¡ã«ããºã ãå¿ èŠã§ãã ãã®å ŽåãGFP_NOFSãã©ã°ã䜿çšãããŸããããã¯ãã¡ã¢ãªã¢ãã±ãŒã¿ãŒããã¡ã€ã«ã·ã¹ãã ããŒã«ã«ã¢ã¯ã»ã¹ããªãããšã瀺ããŸãã
åœç¶ãã¡ã¢ãªãåé¡ãªãå²ãåœãŠãããããšãã«ãŒãã«ã§ãã§ãã¯ããããšãå¿ããªãã§ãã ããã
次ã®ååã¯ã sb_breadé¢æ°ã®åŒã³åºãã§ãã ããã§ã¯ããã£ã¹ã¯ããèªã¿åã£ãŠããŸãïŒ ãã®é¢æ°ã¯ãã¹ãŒããŒãããã¯ãžã®ãã€ã³ã¿ãŒãšèªã¿åããããã¯çªå·ãåãå ¥ããŸã-éåžžã«ç°¡åã§ãã ãã®é¢æ°ã¯ã buffer_headæ§é äœãžã®ãã€ã³ã¿ãŒãè¿ãããããã¯ããŒã¿èªäœã¯ããã®æ§é äœã®b_dataãã£ãŒã«ãããã¢ã¯ã»ã¹ã§ããŸãã
åœç¶ããã®å Žåãèªã¿åããæåããããšã確èªããããšãå¿ããªãã§ãã ããã
次ã«ãcharãžã®ãã€ã³ã¿ãŒãaufs_disk_super_blockæ§é äœãžã®ãã€ã³ã¿ãŒã«å€æããã ãã§ãã aufs_super_block_fillé¢æ°ã¯ãç°åžžãªããšãäœãããã«aufs_disk_super_blockã䜿çšããŠaufs_super_blockæ§é äœãåããŸãã
static inline void aufs_super_block_fill(struct aufs_super_block *asb, struct aufs_disk_super_block const *dsb) { asb->asb_magic = be32_to_cpu(dsb->dsb_magic); asb->asb_inode_blocks = be32_to_cpu(dsb->dsb_inode_blocks); asb->asb_block_size = be32_to_cpu(dsb->dsb_block_size); asb->asb_root_inode = be32_to_cpu(dsb->dsb_root_inode); asb->asb_inodes_in_block = asb->asb_block_size / sizeof(struct aufs_disk_inode); }
ãæ³åã®ãšãããbe32_to_cpué¢æ°ã¯ãæ°å€ãããã°ãšã³ãã£ã¢ã³ãããã©ãããã©ãŒã ã§äœ¿çšããããã€ãé ã«å€æããŸãã
ãããã¯ã®æäœãçµäºãããããããã¯ã解æŸããå¿ èŠããããŸããããã«ã¯brelseé¢æ°ããããŸãã å®éã«ã¯ããã®ãããã¯ã®åç §ã«ãŠã³ããæžãããŸãã åç §ã«ãŠã³ã¿ãŒã0ã«éãããšããã«ãããã¯ã¯ããã«ã¯è§£æŸãããŸãã-ã«ãŒãã«å ã®ãããã¯ã§ã¯ã¬ããŒãžã³ã¬ã¯ã¿ãŒãæ©èœããŸãããæ·±å»ãªå¿ èŠãªããããã¯ã¯è§£æŸãããŸããã ãã®çç±ã¯ããã£ã¹ã¯ããã®ãããã¯ã®èªã¿åãã¯ããªãé«äŸ¡ãªæäœã§ãããããèªã¿åããããã¯ã®ãã£ãã·ã¥ãç¶æããããšã¯åççã§ãããåããããã¯ãå床èªã¿åãå Žåã¯ãèªã¿åããããã¯ãè¿ããŸãïŒãã¡ããããŸã ãã£ãã·ã¥å ã«ããå ŽåïŒã
æåŸã«è¡ãããšã¯ããžãã¯çªå·ã®ç¢ºèªã§ããaufsãå®éã«ãã£ã¹ã¯ã«ä¿åãããŠããããšã確èªããå¿ èŠããããŸãã
gotoã«æ°ä»ãã人ã®ããã«ãgotoã¯ã«ãŒãã«ã§ããªãé »ç¹ã«äœ¿çšãããŸãã åºæ¬çã«ããšã©ãŒåŠçãæŽçããããã«-Cèšèªã«ã¯äŸå€ããªããã¡ã€ã³ã®å®è¡ãã¹ãšãšã©ãŒåŠçãåé¢ãããšããã¢ã€ãã¢ã¯éåžžã«é åçã§ãã ãã®å Žåãgotoã䜿çšããŠãã»ãšãã©äœãåŸãããŸãã-䜿çšçç±ã®äŸãšããŠãããã«æå³çã«æ¿å ¥ããŸããã äžè¬çã«ãã«ãŒãã«ã®éçºè ã®éã§ã¯ããã»ã©åŸè€å«ããªäººã¯ããªãã®ã§ãã³ãŒãå ã«äžéãªæŒç®åãä¹±çšããå ŽæããããŸã-ããã«åããå¿ èŠããããŸãã
æ°é ãã®ããèªè ã¯ããããã1ã€ã®ççŸã«æ³šæãåŒããã§ãããã ãã§ã«è¿°ã¹ãããã«ããã¡ã€ã«ã·ã¹ãã ã¯ããŸããŸãªãããã¯ãµã€ãºã§åäœã§ãããã®æ å ±ã¯ããããã¹ãŒããŒãããã¯ã«æ ŒçŽãããŸãã ããã§ã¯ãã¹ãŒããŒãããã¯ãèªã¿åããšãã«ãsb_breadé¢æ°ã¯ã©ã®ãµã€ãºã®ãããã¯ãèªã¿åããŸããïŒ ç§ãã¡ã®å Žåããã¹ãŠãåçŽã§ããããã©ã«ãã§ã¯ããããã¯ãµã€ãºã¯ãããã¯ããã€ã¹ã®ãããã¯ãµã€ãºïŒãããã¯æ°...ïŒã«èšå®ãããŠããŸãã ãããŠããã®ãµã€ãºãã¹ãŒããŒãããã¯ã®æ§é ã«ååã§ããããšãé¡ã£ãŠããŸã-ç§ãã¡ã®å Žåã¯ããã§ãã
ã¹ãŒããŒãããã¯ãèªã¿åãé¢æ°ãäœæããaufs_fill_superããåŒã³åºããŸãïŒåã®æçš¿ãåç §ïŒãããã¯æ¬¡ã®ããã«ãªããŸãã
static int aufs_fill_sb(struct super_block *sb, void *data, int silent) { struct inode *root = NULL; struct aufs_super_block *asb = aufs_super_block_read(sb); if (!asb) return -EINVAL; sb->s_magic = asb->asb_magic; sb->s_fs_info = asb; sb->s_op = &aufs_super_ops; if (sb_set_blocksize(sb, asb->asb_block_size) == 0) { pr_err("device does not support block size %u\n", (unsigned)asb->asb_block_size); return -EINVAL; } root = aufs_inode_get(sb, asb->asb_root_inode); if (IS_ERR(root)) return PTR_ERR(root); sb->s_root = d_make_root(root); if (!sb->s_root) { pr_err("aufs cannot create root\n"); return -ENOMEM; } return 0; }
åè¿°ããããã«ãs_fs_infoãã£ãŒã«ãã«aufs_super_blockãžã®ãã€ã³ã¿ãŒãä¿åããŸãã ããã«ã sb_set_blocksizeãåŒã³åºããŠãæ£ãããããã¯ãµã€ãºãèšå®ããŸãã é¢æ°å ã§ã³ã¡ã³ããèšã£ãŠããããã«ããããã¯ãµã€ãºã¯512ãã€ãããããŒãžãµã€ãºãŸã§ã§ãªããã°ãªããŸãã-ããããããã¯ãµã€ãºã®éžæã決å®ãããã®ã§ãã ãã¡ã€ã«ã·ã¹ãã ã倧ããªãããã¯ãµã€ãºã§åäœããå Žåãè¿œå ã®äœæ¥ãå¿ èŠã«ãªããŸãïŒããã»ã©å€§ããã¯ãããŸããïŒã
ããã§ãaufs_super_blockãåçã¡ã¢ãªã«å²ãåœãŠãŸãããã€ãŸãã解æŸããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãååã®æçš¿ããå¥ã®é¢æ°ã«ããã€ãã®å€æŽãå ããå¿ èŠããããŸãã
static void aufs_put_super(struct super_block *sb) { struct aufs_super_block *asb = (struct aufs_super_block *)sb->s_fs_info; if (asb) kfree(asb); sb->s_fs_info = NULL; pr_debug("aufs super block destroyed\n"); }
ã«ãŒãã«ã«ã¯ããã€ãã®kfreeå®è£ ãååšããããïŒãŸã ãããšãã ïŒãkfreeé¢æ°ãškmallocé¢æ°ãããã«æ£ç¢ºã«ã¯é¢æ°ãšã®çµã¿åãããæšæž¬ãããããšã¯é£ãããããŸãããã詳现ã¯èª¬æããŸããã
aufs_fill_sbé¢æ°å ã®å¥ã®éèŠãªå€æŽã¯ãaufs_inode_getã®åŒã³åºãã§ãã ååã®èšäºã§ã¯ããããŒã®iããŒããäœæããŸããã次ã«ããã£ã¹ã¯ããããããèªã¿åãæ¹æ³ãåŠç¿ããŸãã
ãããããã®åã«ãèå³æ·±ããã€ã³ãã IS_ERRãšPTR_ERRã®ãã¢ã«æ³šæãåŒããŸãã ãããã¯ãã«ãŒãã«ããã®ã¡ã¢ãªã®å Žæã«é¢ããå®å šãªæ å ±ãæã£ãŠãããšããäºå®ã«åºã¥ããŠããã€ã³ã¿ãŒãæ°å€ã«ããŸãã¯ãã®éã«åçŽã«å€æããŸãããããã£ãŠããã€ã³ã¿ãŒã®ã©ã®ããããä»ã®ç®çã«äœ¿çšã§ãããã«ã€ããŠã ããã¯ããã€ã³ã¿ãŒã®æ§é ã«é¢ããç¥èã䜿çšããæãç°¡åãªäŸã§ã; ã«ãŒãã«ã ãã§ãªã ããã£ãšèå³æ·±ããã®ããããŸã ã
åååºäŒã£ãsuper_operationsæ§é ãå±éããŠãã€ã³ããã¯ã¹ããŒãã®æäœãéå§ããŸãã 次ã®ããã«å ¥åããŸãã
static struct super_operations const aufs_super_ops = { .alloc_inode = aufs_inode_alloc, .destroy_inode = aufs_inode_free, .put_super = aufs_put_super, };
aufs_inode_allocããã³aufs_inode_freeé¢æ°ãžã®ãã€ã³ã¿ãŒãããã«è¿œå ããŸããã ãããã¯ãiããŒãã®å²ãåœãŠãšè§£æŸã®ããã®ç¹å®ã®é¢æ°ã§ããããã§ã¯ãSLABïŒãã®ç£ã¯æ¢ã«kmallocã®åœ¢åŒã§æ€åºãããŠããŸãïŒãšRCUïŒå°ãã°ããïŒã«ééããŸãã
ãã®ãããå¥ã®æ§é ãå®çŸ©ããããšã§ãã€ã³ããã¯ã¹ããŒããžã®ã¡ã¢ãªã®å²ãåœãŠãéå§ããŸããããã¯ãã¡ã¢ãªå ã®ã€ã³ããã¯ã¹ããŒããè¡šããŸãïŒã¹ãŒããŒãããã¯ã®å Žåãšåæ§ïŒã
struct aufs_inode { struct inode ai_inode; uint32_t ai_block; };
ä»åã¯ãæ§æã®ä»£ããã«ãç¶æ¿ãã䜿çšããŸãã Cã§ã®ç¶æ¿ã¯ãŸã£ããããªãããŒã«èŠããŸããïŒCã¯ç¶æ¿ããµããŒãããŠããªãã®ã§ãããã¯é©ãããšã§ã¯ãããŸããïŒã ãããè¡ãã«ã¯ãaufs_inodeæ§é ã®æåã®æ§é ãåºæ¬æ§é ïŒåºæ¬ã¯ã©ã¹ïŒ-i ããŒãæ§é ã«ããã ãã§ãã ãããã£ãŠãaufs_inodeãžã®ãã€ã³ã¿ãŒã¯ãiããŒããžã®ãã€ã³ã¿ãŒãšããŠäœ¿çšã§ããéãåæ§ã§ãïŒãã¡ããããã®ãã€ã³ã¿ãŒãaufs_inodeãç¹ã«åç §ããŠããããšã確å®ã§ãªãéãïŒã
æ§æãšæ¯èŒããŠããç¶æ¿ãèªäœã¯ã«ãŒãã«ããã®ãµããŒããå¿ èŠãšããŸãããããã«ãã¡ã¢ãªå²ãåœãŠã®æ°ã®ç¹ã§ããæçã§ããã¹ãŒããŒãããã¯ã®å Žåã®ããã«ã2ã€ã§ã¯ãªãåã€ã³ããã¯ã¹ããŒãã«1ã€ã®å²ãåœãŠãå¿ èŠã§ãã ãŸããã¹ãŒããŒãããã¯ãšã¯ç°ãªããã»ãšãã©ãã¹ãŠã®å¿ èŠãªãã£ãŒã«ãã¯ãã§ã«iããŒãå ã«ååšããŠããŸãã ãã ãããã¡ã€ã«ã·ã¹ãã ã¯ããŒã¿ãéåžžã«åçŽã«ãã£ã¹ã¯ã«ä¿åãããããããã¯ã«ãŒã«ãããäŸå€ã§ãã
ã€ã³ããã¯ã¹ããŒãã«ã¡ã¢ãªãå²ãåœãŠãã«ã¯ãSLABã¢ãã±ãŒã¿ãŒã䜿çšããŸãã SLABã¢ãã±ãŒã¿ãŒ-åããµã€ãºã®ã¡ã¢ãªãããã¯ãå²ãåœãŠãããšãã§ãããã£ãã·ã¥ã¢ãã±ãŒã¿ãŒã ãã®å¶éã«ãããã¡ã¢ãªç®¡çãç°¡çŽ åãããã¡ã¢ãªå²ãåœãŠãå éããããšæšæž¬ããã®ã¯é£ãããããŸããã SLABã¢ãã±ãŒã¿ãŒã¯ãèŠæ±æã«OSã«å€§éã®ã¡ã¢ãªãã£ã³ã¯ãç §äŒããããããããå°ããªã»ã¯ã·ã§ã³ãå²ãåœãŠãŸããOSã¡ã¢ãªãããŒãžã£ãŒãžã®èŠæ±ã®é »åºŠã¯äœãããŠãŒã¶ãŒèŠæ±ã¯é«éã§ãã
ãã ããæåã¯ãSLABã䜿çšããå Žåã®ã¡ã¢ãªå²ãåœãŠé床ã®åäžã¯ãã¡ã¢ãªç®¡çã®ç°¡çŽ åã ãã§ãªãããã®ã¡ã¢ãªã®åæåã³ã¹ãã®åæžã«ãããã®ã§ããïŒããã»ã©ã§ã¯ãããŸããã§ããïŒã å®éãSLABã¢ãã±ãŒã¿ãŒã¯ãåããµã€ãºã®ãªããžã§ã¯ããéžæããããã ãã§ãªããåãã¿ã€ãã®ãªããžã§ã¯ããéžæããããã«ãã䜿çšãããŸããããã«ããã1ã€ã®ã¡ã¢ãªãåå²ãåœãŠãããšãã«äžéšã®ãã£ãŒã«ãã®åæåãã¹ãããã§ããŸãã ããšãã°ããã¥ãŒããã¯ã¹ãã¹ãã³ããã¯ãããã³ãã®ä»ã®åæ§ã®ãªããžã§ã¯ãã¯ããªããžã§ã¯ãããªãªãŒã¹ãããšãã«ãæ£ãããå€ãæã£ãŠããå¯èœæ§ãé«ããåå²ãåœãŠãããšãã«ååæåããå¿ èŠã¯ãããŸããã 詳现ãšæž¬å®çµæã«ã€ããŠã¯ãå ã®èšäºãåç §ããŠãã ãã ã
çŸåšãLinuxã«ã¯3ã€ã®ç°ãªãã¿ã€ãã®SLABã¢ãã±ãŒã¿ãŒãSLABãSLUBãSLOBããããŸãã ãããã®éãã«ã€ããŠã¯è§ŠããŸããããåãã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãã ãããã£ãŠãSLABã¢ãã±ãŒã¿ãŒãäœæããã«ã¯ã次ã®é¢æ°ã䜿çšããŸãã
int aufs_inode_cache_create(void) { aufs_inode_cache = kmem_cache_create("aufs_inode", sizeof(struct aufs_inode), 0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), aufs_inode_init_once); if (aufs_inode_cache == NULL) return -ENOMEM; return 0; }
SLABãäœæãããšããkmem_cache_createé¢æ°ã«ã¯ ããªããžã§ã¯ãã®ååããµã€ãºãåæåé¢æ°ïŒãªããžã§ã¯ããæåã«éžæããããšãã«1åã ãåŒã³åºãããé¢æ°ïŒãããã³ç§ãå ¥åããªãããã€ãã®ãã©ã¡ãŒã¿ãŒãæž¡ãããŸãã ããããæ å ±ãªãã§èå³ã®ãã人ããŸã£ããæ®ããªãããã«ããã¹ãŠã®ãã¡ã€ã«ã·ã¹ãã ã®ã€ã³ããã¯ã¹ããŒãçšã®ã¹ã©ãã®äœæã¯åãã«èŠãããšèšããŸã-éãã¯éèŠã§ã¯ãããŸããã
ã«ãŒãã«ã«ãã¡ã€ã«ã·ã¹ãã ãç»é²ããåã«ãã¢ãžã¥ãŒã«ãããŒããããšãã«aufs_inode_cache_createé¢æ°ãåŒã³åºããŸããã¢ãžã¥ãŒã«ãã¢ã³ããŒãããããšãã«åŒã³åºããã¢é¢æ°ããããŸãã
void aufs_inode_cache_destroy(void) { rcu_barrier(); kmem_cache_destroy(aufs_inode_cache); aufs_inode_cache = NULL; }
kmem_cache_destroyé¢æ°ã¯ãSLABã¢ãã±ãŒã¿ãŒãç Žå£ããŸããç Žå£ã®æç¹ãŸã§ã«ããã®ãã£ãã·ã¥ãããã¹ãŠã®ãªããžã§ã¯ãã解æŸããå¿ èŠããããŸããããããªããšãã·ã¹ãã ãã°ã«äžå¿«ãªãšã©ãŒã¡ãã»ãŒãžãšããã£ãããã«ãããã©ãã«ãå€æ°çºçããŸãã
çŽæãããRCUã®ã¿ãããäžèšã§èšãã°ãRCUã¯ã«ãŒãã«å ã®äžè¬çãªåæã¡ã«ããºã ïŒããã³ããã¯ããªãŒã¢ã«ãŽãªãºã ã®å®å šãªã¡ã¢ãªãªãªãŒã¹ïŒã§ãã RCUèªäœã¯Habréäžã®å¥ã®èšäºãããå€ããããã«ãããã«ããã®ææ³ã®äœæè ã§ãããLinuxã«ãŒãã«ã®RCUã¡ã³ãããŒã¯ã圌ã®é è³ã«è§Šããæ¬å šäœãæžããŸããã
ããããç§ãã¡ã¯åç©åå šäœã®RCUæ©èœããrcu_barrierã ããæ±ãå¿ èŠããããŸããïŒkfreeãšåæ§ã«ããã®é¢æ°ã®å¥ã®å®è£ ãããã«ãããŸãïŒãç°¡åãªæ¹æ³ã§ããã°ããã®é¢æ°ã¯ãä¿è·ãããŠããRCUããŒã¿ã«å¯Ÿããä¿çäžã®ãã¹ãŠã®äœæ¥ãå®äºãããŸã§åŸ æ©ãããã®åŸãåŒã³åºãå ã®ãŠãŒã¶ãŒãã€ãŸãããããã³ã°é¢æ°ã«å¶åŸ¡ãæ»ããŸãããªããããå¿ èŠãªã®ããããå°ãäœããªããŸãã
ã¡ã¢ãªã®å²ãåœãŠã«æ»ããŸããããæ¢ã«è¿°ã¹ãæ©èœãèããŠã¿ãŸãããã
struct inode *aufs_inode_alloc(struct super_block *sb) { struct aufs_inode *const i = (struct aufs_inode *) kmem_cache_alloc(aufs_inode_cache, GFP_KERNEL); if (!i) return NULL; return &i->ai_inode; }
以åã«äœæãããSLABã¢ãã±ãŒã¿ãŒãïŒkmem_cache_allocå®è£ ã®1ã€ã䜿çšããŠïŒäœ¿çšããinodeãžã®ãã€ã³ã¿ãŒãè¿ããŸã-ç°åžžãªããšã¯ãããŸãããããªãªãŒã¹é¢æ°ã¯ããå°ãèå³æ·±ãã§ãïŒ
void aufs_inode_free(struct inode *inode) { call_rcu(&inode->i_rcu, aufs_free_callback); }
ããã§åã³RCUã«çŽé¢ããŸããããã§ãããã¯ããªãŒã¢ã«ãŽãªãºã ã«ã€ããŠå°ã説æãã䟡å€ããããŸãããã®ãããªã¢ã«ãŽãªãºã ã®åââé¡ã¯ãããã¯ããªããšããªããžã§ã¯ããä»ã®å®è¡ã¹ã¬ãããšäžŠè¡ããŠäœ¿çšãããªããšããä¿èšŒããªãããšã§ããã€ãŸãããã®ãªããžã§ã¯ããå æããã¡ã¢ãªã解æŸã§ããŸããã圌ããããã£ãŠãããã¯ããªãŒã¢ã«ãŽãªãºã ã§ã¯ãã¡ã¢ãªãå®å šã«è§£æŸããããã®æŠç¥ãæ€èšããå¿ èŠããããRCUã¯ãã®åé¡ã解決ããããŒã«ãæäŸããŸããcall_rcué¢æ°ã®ãã¹ãŠã®å®è£ ã¯ãå®å šã«ãªããŸã§äžéšã®é¢æ°ïŒãã®å Žåã¯aufs_free_callbackãªãªãŒã¹é¢æ°ïŒã®å®è¡ãé ãããŸãããããŠããã§ã«äžã§è¿°ã¹ãrcu_barrierã¯ããã¹ãŠã®ä¿çäžã®æ©èœã®å®äºãåŸ ã£ãŠããŸãã
ç²ããŠããŸãã 倧äžå€«ããã§ã«ãã£ããŒã¬ã«è¿ã¥ããŠããŸãã次ã«ããã£ã¹ã¯ããã€ã³ããã¯ã¹ããŒããèªã¿åããŸãããããè¡ãããã«ããã§ã«è¿°ã¹ãaufs_inode_geté¢æ°ãäœæããŸããã
struct inode *aufs_inode_get(struct super_block *sb, uint32_t no) { struct aufs_super_block const *const asb = AUFS_SB(sb); struct buffer_head *bh = NULL; struct aufs_disk_inode *di = NULL; struct aufs_inode *ai = NULL; struct inode *inode = NULL; uint32_t block = 0, offset = 0; inode = iget_locked(sb, no); if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; ai = AUFS_INODE(inode); block = aufs_inode_block(asb, no); offset = aufs_inode_offset(asb, no); pr_debug("aufs reads inode %u from %u block with offset %u\n", (unsigned)no, (unsigned)block, (unsigned)offset); bh = sb_bread(sb, block); if (!bh) { pr_err("cannot read block %u\n", (unsigned)block); goto read_error; } di = (struct aufs_disk_inode *)(bh->b_data + offset); aufs_inode_fill(ai, di); brelse(bh); unlock_new_inode(inode); return inode; read_error: pr_err("aufs cannot read inode %u\n", (unsigned)no); iget_failed(inode); return ERR_PTR(-EIO); }
ç°¡åãªãã€ã³ãããå§ããŸã-AUFS_SBé¢æ°ãšAUFS_INODEé¢æ°ã䜿çšãããšãããããsuper_blockãšiããŒããžã®ãã€ã³ã¿ãŒãä»ããŠãaufs_super_blockãšaufs_inodeæ§é ãžã®ãã€ã³ã¿ãŒãååŸã§ããŸãããããã®æ§é ãã©ã®ããã«æ¥ç¶ãããŠãããã«ã€ããŠã¯ãã§ã«äžã§èª¬æããã®ã§ããããã®ã³ãŒãã¯æäŸããŸããïŒéåžžã«åçŽã§ãïŒã
aufs_inode_blocké¢æ°ãšaufs_inode_offseté¢æ°ã䜿çšãããšãã€ã³ããã¯ã¹ããŒãçªå·ã§ãããã¯å ã®ãããã¯çªå·ãšãªãã»ãããååŸã§ããŸããéæ³ãåçŽãªç®è¡æŒç®ããªãããããããã«ã€ããŠã詳ãã説æããŸããã
ãããŠä»ãèå³æ·±ãç¹ã®ããã«-ããã€ãã®iget_lockedããã³unlock_new_inodeé¢æ°ããããã¯ã®å Žåãšåæ§ã«ãã«ãŒãã«ã¯iããŒããã£ãã·ã¥ããµããŒãããŸããããã¯ããã£ã¹ã¯ããã€ã³ããã¯ã¹ããŒããå床èªã¿åããªãããã ãã«å¿ èŠãªããã§ã¯ãããŸãããå®éã«ã¯ãåããã¡ã€ã«/ãã£ã¬ã¯ããªãè€æ°ã®ããã»ã¹ã§äžåºŠã«éãããšãã§ããŸãããã®å Žåããã¹ãŠã®ããã»ã¹ã¯ãiããŒãã®1ã€ã®ã€ã³ã¹ã¿ã³ã¹ã§åäœããŠãçžäºã«åæããå¿ èŠããããŸãããããã¯ã«ã€ããŠãåæ§ã®è°è«ãåœãŠã¯ãŸããŸãããããããããã¯ãããã¯ã«ãåœãŠã¯ãŸãã§ãããã
ãã®ãããidet_lockedé¢æ°ã¯ãŸããã£ãã·ã¥å ã§iããŒããæ¢ããiããŒããèŠã€ãããªãå Žåã¯æ°ããiããŒãã«ã¡ã¢ãªãå²ãåœãŠãŸããã€ã³ããã¯ã¹ããŒããåå²ãåœãŠããããããã£ãã·ã¥ã«èŠã€ãããªãã£ãå Žåãi_stateãã£ãŒã«ãã«I_NEWãã©ã°ãèšå®ããããã®ããŒãã®ã¹ãã³ããã¯ïŒi_lockãã£ãŒã«ãïŒããã£ããã£ãããŸãããããã£ãŠãé¢æ°ã¯æåã«i_stateãã£ãŒã«ãããã§ãã¯ããI_NEWãã©ã°ãã¯ãªã¢ãããŠããå Žåã¯ããã£ãã·ã¥ãããiããŒããè¿ãã ãã§ãããã以å€ã®å Žåã¯ãinodeãåããå¿ èŠããããŸãããã®ããã«ããã£ã¹ã¯ããç®çã®ãããã¯ãèªã¿åããŸãïŒæ¢ç¥ã®sb_breadã䜿çšïŒã
aufs_inode_fillé¢æ°ã¯åã«å å¡«ãè¡ããŸãïŒ
static void aufs_inode_fill(struct aufs_inode *ai, struct aufs_disk_inode const *di) { ai->ai_block = be32_to_cpu(di->di_first); ai->ai_inode.i_mode = be32_to_cpu(di->di_mode); ai->ai_inode.i_size = be32_to_cpu(di->di_size); ai->ai_inode.i_blocks = be32_to_cpu(di->di_blocks); ai->ai_inode.i_ctime.tv_sec = be64_to_cpu(di->di_ctime); ai->ai_inode.i_mtime.tv_sec = ai->ai_inode.i_atime.tv_sec = ai->ai_inode.i_ctime.tv_sec; ai->ai_inode.i_mtime.tv_nsec = ai->ai_inode.i_atime.tv_nsec = ai->ai_inode.i_ctime.tv_nsec = 0; i_uid_write(&ai->ai_inode, (uid_t)be32_to_cpu(di->di_uid)); i_gid_write(&ai->ai_inode, (gid_t)be32_to_cpu(di->di_gid)); }
ããã§ããæ©èœã®ã«ããã«ä»¥å€ã®éæ³ã¯ãi_uid_writeãªããši_gid_writeããã ããç¹å¥ãªããšã¯äœãè¡ããŸããã察å¿ãããã£ãŒã«ãã«å€ãå²ãåœãŠãã ãã§ãã
ããã«ãtimespecæ§é äœãšããŠã®æéã®è¡šç€ºã«æ³šæãåããŸãããã®æ§é äœã¯ãç§ãšããç§ã®æ°ã®ãã¢ã®ã¿ã§æ§æãããŠããŸããã€ãŸããæœåšçã«æéãéåžžã«æ£ç¢ºã«ä¿åã§ããŸãã
æåŸã«ãé¢æ°ã®æåŸã§ãã¹ãã³ããã¯ã解æŸããŠãã€ã³ã¿ãŒãè¿ãå¿ èŠããããŸãããã®ããã«ã¯ãunlock_new_inodeé¢æ°ã䜿çšããŸãã
çµè«ã®ä»£ããã«
æçš¿ã¯æ¬åœã«å€§ããããšãå€æããããã§ããã¹ãŠã®ãã€ã³ããã«ããŒããŠããŸãããå®è£ ã®ãã¹ãŠã®éèŠãªéšåã説æããããšããŸããã
ãã¹ãŠã®ãœãŒã¹ã³ãŒãã¯ãã¡ãããå ¥æã§ããŸãããªããžããªã«ã¯ãã«ãŒãã³ã°ãšãŠãŒã¶ãŒã®2ã€ã®ãã©ã«ããŒããããŸããæšæž¬ããã®ã¯é£ãããããŸããã1ã€ã¯ã¢ãžã¥ãŒã«ã®ã³ãŒããä¿åãã2ã€ç®ã¯ãã©ãŒãããçšã®ãŠãŒãã£ãªãã£ã®ã³ãŒããä¿åããŸããã³ãŒãã倧ãããªã£ãããããšã©ãŒãçºçããå¯èœæ§ã倧ãããªããŸãããã³ã¡ã³ããä¿®æ£ã建èšçãªæ¹å€ããã«ãªã¯ãšã¹ããæè¿ããŸãã
ããŠã³ãçšã®ãã£ã¹ã¯ã€ã¡ãŒãžãååŸããã«ã¯ã次ã®ããã«ããŸãã
dd bs=1M count=100 if=/dev/zero of=image ./mkfs.aufs ./image
ããã§ãåã®æçš¿ã§ç€ºããããã«ç»åãã¡ã€ã«ã䜿çšã§ããŸãã
ãã®èšäºã®ã³ãŒãäŸãããµã³ãã«åºåã®äžéšãåé€ããŸãããããªããžããªã®ã³ãŒãã䜿çšããå Žåã¯ãdmesgã³ãã³ãã䜿çšããŠã¢ãžã¥ãŒã«ãæ©èœããããšã確èªã§ããŸãã