¿¡ Á¤ÀÇµÈ xfs_dinode_t (disk inode) ±¸Á¶Ã¼°¡ ³ªÅ¸³½´Ù. XFSÀÇ ¾ÆÀ̳ëµå´Â Çʿ信 µû¶ó Å©±â°¡ Áõ°¡µÉ ¼ö ÀÖ´Â °¡º¯ÀûÀÎ ±¸Á¶À̹ǷΠÇÙ½ÉÀÌ µÇ´Â xfs_dinode_core_t ±¸Á¶Ã¼°¡ ³ªÅ¸³»´Â Çì´õ Á¤º¸¸¦ ¾Õ¿¡ Æ÷ÇÔÇϰí, Çʿ信 µû¶ó unionÀ¸·Î Á¤ÀÇµÈ ¸â¹öµéÀ» Ãß°¡Çϵµ·Ï ÇÑ´Ù. xfs_dinode_core_t¿¡ Æ÷ÇÔµÈ ½Ã°£ Á¤º¸(atime, mtime, ctime)µéÀº ´ÙÀ½ÀÇ ±¸Á¶Ã¼¿¡¼ º¼ ¼ö ÀÖµíÀÌ 64ºñÆ®·Î °ü¸®µÈ´Ù.
typedef struct xfs_timestamp {
__int32_t t_sec; /* timestamp seconds */
__int32_t t_nsec; /* timestamp nanoseconds */
} xfs_timestamp_t;
µð·ºÅ丮 ±¸Á¶
XFSÀÇ µð·ºÅ丮 ±¸Á¶´Â ¹öÀü 1, 2ÀÇ µÎ °¡Áö·Î ³ª´¶´Ù. ¹öÀü 1¿¡¼´Â µð·ºÅ丮 ³»ÀÇ ¸ðµç Á¤º¸°¡ ¾ÆÀ̳ëµå ³»¿¡ Æ÷Ç﵃ ¸¸Å ÀÛÀº °æ¿ì¿¡´Â º°µµÀÇ ºí·°À» ÇÒ´çÇÏÁö ¾Ê°í, ¾ÆÀ̳ëµå ³»¿¡ µð·ºÅ丮 Á¤º¸¸¦ À¯ÁöÇÏ´Â short form°ú º°µµÀÇ B+ Æ®¸® ºí·°À» ÇÒ´çÇÏ¿© Á¤º¸¸¦ ÀúÀåÇÏ´Â large formÀÌ ÀÖ´Ù. ¹öÀü 2¿¡¼´Â À̸¦ È®ÀåÇÏ¿© <Ç¥ 1>°ú °°ÀÌ ÃÑ 4°¡Áö °æ¿ì°¡ °¡´ÉÇÏ´Ù.
 |
| <Ç¥ > XFSÀÇ µð·ºÅ丮 ±¸Á¶(¹öÀü 2) |
B+ Æ®¸®¿¡¼ »ç¿ëµÇ´Â ºí·°µé¿¡ ´ëÇØ¼´Â ÀÌÈÄ¿¡ Á» ´õ ÀÚ¼¼È÷ »ìÆìº¸±â·Î ÇÏÀÚ.
XFSÀÇ ÀÚ·á ±¸Á¶
B Æ®¸®
B Æ®¸®´Â º»·¡ µð½ºÅ©¿Í °°Àº º¸Á¶ ±â¾ï ÀåÄ¡¿¡¼ »ç¿ëµÇ±â À§ÇØ ¿¬±¸µÈ ±ÕÇü Ž»ö Æ®¸®·Î µð½ºÅ©ÀÇ I/O ¿¬»êÀ» ÃÖ¼ÒÈÇϵµ·Ï ¼³°èµÇ¾ú´Ù. B Æ®¸®ÀÇ ³ëµå´Â ÀÏ¹Ý ÀÌÁø Æ®¸®¿Í´Â ´Þ¸® ¸Å¿ì ¸¹Àº ÀÚ½Ä ³ëµå¸¦ °¡Áú ¼ö ÀÖ´Ù. À̸¦ ¡®Branching factor¡¯¶ó°í ÇÏ¸ç º¸Åë ¼öõ °³ÀÇ ÀÚ½Ä ³ëµå¸¦ °¡Áö´Âµ¥ ÀÌ´Â µð½ºÅ©ÀÇ ºí·° Å©±â¿¡ µû¶ó °áÁ¤µÈ´Ù. µû¶ó¼ B Æ®¸®ÀÇ ³ôÀÌ´Â ÀÏ¹Ý ÀÌÁø Æ®¸®º¸´Ù ÈξÀ ³·¾ÆÁö°Ô µÇ¹Ç·Î ¹æ¹®ÇØ¾ß ÇÒ ³ëµåÀÇ ¼ö°¡ ÁÙ¾îµé°Ô µÈ´Ù.
 |
| <±×¸² 1> B Æ®¸®ÀÇ ±¸Á¶ |
<±×¸² 1>¿¡¼ °¢ ³ëµå¿¡ Æ÷ÇÔµÈ ¾ËÆÄºªÀº °Ë»ö¿¡ »ç¿ëµÉ ۸¦ ³ªÅ¸³½´Ù. °¢°¢ÀÇ Å°´Â ±×¿¡ ¿¬°üµÈ µ¥ÀÌÅ͸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ Á¤º¸¸¦ ÇÔ²² À¯ÁöÇϰí ÀÖ´Ù. ·çÆ®°¡ ¾Æ´Ñ ³ëµå´Â ÃÖ¼Ò t°³¿¡¼ ÃÖ´ë 2t°³±îÁöÀÇ ÀÚ½ÄÀ» °¡Áú ¼ö ÀÖ´Ù. (t´Â 2 ÀÌ»óÀÇ Á¤¼ö) ¾ÕÀÇ ¿¹Á¦¿¡¼ t = 2°¡ µÇÁö¸¸ º¸Åë tÀÇ °ªÀº À̺¸´Ù ¸Å¿ì Å« °ªÀÌ µÈ´Ù.
B+ Æ®¸®
B+ Æ®¸®´Â B Æ®¸®ÀÇ º¯ÇüÀ¸·Î ±âº»ÀûÀÎ °³³äÀº B Æ®¸®¿Í À¯»çÇÏÁö¸¸ ¼øÂ÷ÀûÀÎ Á¢±ÙÀÇ È¿À²¼ºÀ» ³ôÀ̱â À§ÇØ ¸ðµç µ¥ÀÌÅ͸¦ ¸®ÇÁ ³ëµå¿¡ À¯ÁöÇϰí À̸¦ ¼øÂ÷ÀûÀ¸·Î ¿¬°áÇÑ ±¸Á¶ÀÌ´Ù.
 |
| <±×¸² 2> B+ Æ®¸®ÀÇ ±¸Á¶ |
B+ Æ®¸®¿¡¼ Áß°£ ³ëµå¿¡ Àִ Ű °ªÀº ¸®ÇÁ ³ëµå¿¡ Àִ Ű °ªÀ» ã¾Æ°¥ ¼ö ÀÖ´Â °æ·Î·Î¸¸ Á¦°øµÇ¹Ç·Î Áß°£ ³ëµå¿¡ Àִ Ű °ªÀº ¸ðµÎ ¸®ÇÁ ³ëµå¿¡ ´Ù½Ã ³ªÅ¸³´Ù. ¸®ÇÁ ³ëµåµéÀº ¸ðµÎ ¸µÅ©µå ¸®½ºÆ®·Î ¿¬°áµÅ ÀÖÀ¸¹Ç·Î ÆÄÀÏÀÇ ³»¿ëÀ» ¼ø¼´ë·Î Àд °æ¿ì¿Í °°Àº ¼øÂ÷Àû Á¢±Ù 󸮿¡ È¿À²ÀûÀÌ´Ù.
XFSÀÇ B+ Æ®¸® ±¸Á¶
XFS¿¡¼ »ç¿ëµÇ´Â B+ Æ®¸®´Â ¾Õ¿¡¼ »ìÆìºÃµíÀÌ Áß°£ ³ëµåÀÎ °æ¿ì xfs_da_intnode_t ±¸Á¶Ã¼·Î, ¸®ÇÁ ³ëµåÀÎ °æ¿ì xfs_dir2_leaf_t ±¸Á¶Ã¼·Î Á¤ÀǵȴÙ.
 |
| <±×¸² 3> XFSÀÇ B+ Æ®¸® ³ëµå ±¸Á¶ |
Áß°£ ³ëµå¿Í ¸®ÇÁ ³ëµå ¸ðµÎ °ÅÀÇ ºñ½ÁÇÑ Çì´õ Çü½ÄÀ» »ç¿ëÇÑ´Ù. hdr ±¸Á¶Ã¼ÀÇ forw¿Í back ¸â¹ö´Â ÀÌÁß ¸µÅ©µå ¸®½ºÆ®¸¦ °ü¸®Çϱâ À§ÇØ »ç¿ëµÇ¸ç magic °ªÀº °¢°¢ XFS_DA_NODE_MAGIC (0xfebe)¿Í XFS_DIR2_LEAFN_MAGIC (0xd2ff) °ªÀÌ »ç¿ëµÈ´Ù. pad ¸â¹ö´Â ±¸Á¶Ã¼ÀÇ Á¤·ÄÀ» À§ÇØ µé¾î°£ ÀÇ¹Ì ¾ø´Â º¯¼öÀÌ´Ù.
¸ÕÀú Áß°£ ³ëµåºÎÅÍ »ìÆìº¸¸é count ¸â¹ö´Â ÇöÀç ³ëµå¿¡ Æ÷ÇÔµÈ Àüü ¿£Æ®¸®(btree)ÀÇ ¼öÀ̰í, levelÀº ¸®ÇÁ ³ëµå¿¡¼ºÎÅÍÀÇ ³ôÀ̸¦ ³ªÅ¸³½´Ù. °¢°¢ÀÇ ¿£Æ®¸®´Â xfs_da_node_entry ±¸Á¶Ã¼·Î¼ hashval°ú before¶ó´Â ¸â¹ö¸¦ °¡Áö´Âµ¥ hashvalÀº Ű·Î »ç¿ëµÇ°í before ¸â¹ö´Â ÇØ´ç Űº¸´Ù ¾ÕÂÊ¿¡ Á¸ÀçÇÏ´Â µ¥ÀÌÅÍ(ºí·° ¹øÈ£)¸¦ ÀúÀåÇÑ´Ù. xfs_da_intnode_t ±¸Á¶Ã¼¿¡´Â Ãʱ⿡ ¿ÀÁ÷ ÇϳªÀÇ btree ±¸Á¶Ã¼ ¸¸ÀÌ Á¸ÀçÇÏÁö¸¸ »õ·Î¿î ºí·°ÀÌ ÇÒ´çµÇ´Â °æ¿ì xfs_da_node_add() ÇÔ¼ö¿¡ ÀÇÇØ »õ·Î¿î ±¸Á¶Ã¼°¡ ÇÒ´çµÇ¾î btree ¹è¿¿¡ Ãß°¡µÈ´Ù.
¸®ÇÁ ³ëµåµµ ºñ½ÁÇÑ ¹æ½ÄÀ¸·Î Á¤º¸¸¦ ÀúÀåÇϴµ¥ count¿¡´Â Àüü ¿£Æ®¸®ÀÇ ¼ö¸¦, stale¿¡´Â Á¦°ÅÇÒ ¼ö ÀÖ´Â ¿À·¡µÈ ¿£Æ®¸®ÀÇ ¼ö¸¦ ÀúÀåÇÑ´Ù. °¢°¢ÀÇ ¿£Æ®¸®´Â xfs_dir2_leaf_entry_t ±¸Á¶Ã¼·Î¼ ¸¶Âù°¡Áö·Î hashval°ú address¶ó´Â ¸â¹ö¸¦ °¡Áø´Ù. hashvalÀº Áß°£ ³ëµå¿¡¼Ã³·³ Ű·Î »ç¿ëµÇ°í address ¸â¹ö¿¡´Â ½ÇÁ¦ µ¥ÀÌÅͰ¡ ÀúÀåµÈ ºí·°ÀÇ ÁÖ¼Ò¸¦ ÀúÀåÇÑ´Ù.
XFS ÃʱâÈ
XFSÀÇ ÃʱâÈ ·çƾÀº <fs/xfs/linux-2.6/xfs_super.c> ÆÄÀÏ¿¡ Á¤ÀǵǾî ÀÖ´Â init_xfs_fs() ÇÔ¼ö°¡ ¸Ã¾Æ ¼öÇàÇÑ´Ù.
STATIC int __init
init_xfs_fs( void )
{
int error;
struct sysinfo si;
static char message[] __initdata = KERN_INFO \
XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
printk(message);
si_meminfo(&si);
xfs_physmem = si.totalram;
ktrace_init(64);
error = init_inodecache();
if (error < 0)
goto undo_inodecache;
error = pagebuf_init();
if (error < 0)
goto undo_pagebuf;
vn_init();
xfs_init();
uuid_init();
vfs_initquota();
xfs_inode_shaker = kmem_shake_register(xfs_inode_shake);
if (!xfs_inode_shaker) {
error = -ENOMEM;
goto undo_shaker;
}
error = xfs_ioctl32_init();
if (error)
goto undo_ioctl32;
error = register_filesystem(&xfs_fs_type);
if (error)
goto undo_register;
XFS_DM_INIT(&xfs_fs_type);
return 0;
¸ÕÀú XFS°¡ ½ÃÀ۵ƴٴ ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÑ µÚ ½Ã½ºÅÛÀÇ ¸Þ¸ð¸® Á¤º¸¸¦ Àоî¿Í XFS°¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ¸Þ¸ð¸®ÀÇ ¾çÀ» °áÁ¤ÇÑ´Ù. ±×¸®°í µð¹ö±ë Á¤º¸¸¦ À§ÇÑ ktrace ¿µ¿ªÀ» ÇÒ´çÇÑ µÚ inode ij½Ã¸¦ ÃʱâÈÇÑ´Ù. ±×¸®°í pagebuf µ¥¸ó°ú ±×¿¡ °ü·ÃµÈ ´Ù¸¥ µ¥¸óµéÀ» ÃʱâÈÇÑ´Ù. ÀÌµé µ¥¸óÀÇ ¿ªÇÒ¿¡ ´ëÇØ¼´Â ´ÙÀ½¿¡ ÀÚ¼¼È÷ »ìÆìº¸±â·Î ÇÑ´Ù. ±×¸®°í´Â °¢°¢ÀÇ ÃʱâÈ ÇÔ¼öµéÀ» È£ÃâÇÑ´Ù.
¸ÕÀú vn_init() ÇÔ¼ö´Â <fs/xfs/linux/xfs_vnode.c>¿¡ Á¤ÀǵǾî ÀÖÀ¸¸ç vsync ¹è¿¿¡ ¼ÓÇÑ °¢ µ¿±âÈ º¯¼öµéÀ» init_waitqueue_head() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ÃʱâÈÇÑ´Ù. ´ÙÀ½À¸·Î xfs_init() ÇÔ¼ö´Â <fs/xfs/xfs_vfsops.c>¿¡ Á¤ÀǵǾî ÀÖÀ¸¸ç XFS¿¡¼ »ç¿ëµÇ´Â ÇÙ½É ÀÚ·á ±¸Á¶µé(ºí·° ¸ÊÇÎÀ» À§ÇÑ ÇÁ¸® ¸®½ºÆ®, B+ Æ®¸®¿¡¼ »ç¿ëµÇ´Â Ä¿¼, ¾ÆÀ̳ëµå, Æ®·£Àè¼Ç ±¸Á¶Ã¼)À» ÃʱâÈÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù. ±×¸®°í UUID¿Í quota °ü¸®¿¡ ÇÊ¿äÇÑ Ãʱâȸ¦ ÇÑ µÚ ¾ÆÀ̳ëµå ij½Ã¸¦ °ü¸®Çϱâ À§ÇÑ xfs_inode_shake¸¦ µî·ÏÇÑ´Ù. ±×¸®°í 64ºñÆ®¿Í 32ºñÆ® ½Ã½ºÅÛ °£ÀÇ ioctl ȣȯ¼ºÀ» À§ÇØ xfs_ioctl32_init() ÇÔ¼ö¸¦ ¼öÇàÇÑ µÚ ÆÄÀÏ ½Ã½ºÅÛÀ» µî·ÏÇϰí XFS_DM_INIT() ¸ÅÅ©·Î¸¦ È£ÃâÇÏ¿© µ¥ÀÌÅÍ °ü¸® ¿¬»ê¿¡ ÇÊ¿äÇÑ Ãʱâȸ¦ ¼öÇàÇÑ´Ù.
ÆÄÀÏ ½Ã½ºÅÛ ¸¶¿îÆ®
XFS´Â <fs/xfs/linux-2.6/xfs_super.c>¿¡ ´ÙÀ½°ú °°ÀÌ ¼³Á¤µÇ¾î ÀÖ´Ù.
STATIC struct file_system_type xfs_fs_type = {
.owner = THIS_MODULE,
.name = "xfs",
.get_sb = linvfs_get_sb,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
¸¶¿îÆ® °úÁ¤¿¡¼ ÆÄÀÏ ½Ã½ºÅÛ À̸§À¸·Î °Ë»öÇÑ file_system_type ±¸Á¶Ã¼ÀÇ get_sb ÇÔ¼ö°¡ È£ÃâµÈ´Ù. linvfs_get_sb ÇÔ¼ö´Â linvfs_fill_super() ÇÔ¼ö¿Í ÇÔ²² get_sb_bdev() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ºí·° µð¹ÙÀ̽ºÀÇ 0¹ø ºí·° µ¥ÀÌÅ͸¦ ÀÐÀº ÈÄ¿¡ linvfs_fill_super() ÇÔ¼ö¿¡ µ¥ÀÌÅ͸¦ ³Ñ°Ü XFSÀÇ ½´ÆÛ ºí·° ±¸Á¶Ã¼ÀÇ Á¤º¸¸¦ ¿Ã¹Ù·Î ¼³Á¤ÇÑ´Ù.
linvfs_fill_super() ÇÔ¼ö´Â bhv_insert_all_vfsops() ÇÔ¼ö¸¦ ÅëÇØ °¡»ó ÆÄÀÏ ½Ã½ºÅÛ¿¡¼ Áö¿øÇÏ´Â °¢Á¾ ¿¬»êµé°ú quota management¿Í data management¿¡ ÇÊ¿äÇÑ ¿¬»êµéÀ» vfs ±¸Á¶Ã¼¿¡ ¼³Á¤ÇÑ´Ù. ±×¸®°í´Â VFS_PARSEARG() ¸ÅÅ©·Î¸¦ È£ÃâÇÏ¿© ¸¶¿îÆ®½ÃÀÇ ¿É¼ÇµéÀ» xfs_mount_args ±¸Á¶Ã¼¿¡ ÀúÀåÇÑ µÚ VFS_MOUNT() ¸ÅÅ©·Î¸¦ È£ÃâÇÏ¿© ½ÇÁ¦ ¸¶¿îÆ® ¿¬»êÀ» ¼öÇàÇÏ´Â xfs_mount() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ±×¸®°í d_alloc_root() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ·çÆ® µð·ºÅ丮 ¿£Æ®¸®(¡°/¡±)¸¦ ÇÒ´çÇϰí linvfs_start_syncd() ÇÔ¼ö¸¦ ÅëÇØ xfssyncd µ¥¸óÀ» »ý¼ºÇÏ¿© ¼öÇà½ÃŲ´Ù.
xfs_mount() ÇÔ¼ö´Â <fs/xfs/xfs_vfsops.c> ÆÄÀÏ¿¡ Á¤ÀǵǾî Àִµ¥ XFSÀÇ ÆÄƼ¼ÇÀº µ¥ÀÌÅÍ¿Í ·Î±× Á¤º¸°¡ ÇϳªÀÇ ³í¸® º¼·ý ³»¿¡ ±â·ÏµÇ´Â °æ¿ì, µ¥ÀÌÅÍ¿Í ·Î±× Á¤º¸°¡ º°µµÀÇ ¼ºê º¼·ýÀ¸·Î ±â·ÏµÇ´Â °æ¿ì, µ¥ÀÌÅÍ¿Í ·Î±× Á¤º¸¿¡ ½Ç½Ã°£ ¼ºê º¼·ýÀÌ Ãß°¡µÇ´Â 3°¡Áö °æ¿ì°¡ ÀÖÀ» ¼ö ÀÖÀ¸¹Ç·Î À̸¦ ¸ðµÎ ó¸®ÇÒ ¼ö ÀÖµµ·Ï µÇ¾î ÀÖ´Ù.
STATIC int
xfs_mount(
struct bhv_desc *bhvp,
struct xfs_mount_args *args,
cred_t *credp)
{
struct vfs *vfsp = bhvtovfs(bhvp);
struct bhv_desc *p;
struct xfs_mount *mp = XFS_BHVTOM(bhvp);
struct block_device *ddev, *logdev, *rtdev;
int flags = 0, error;
ddev = vfsp->vfs_super->s_bdev;
logdev = rtdev = NULL;
/*
* Setup xfs_mount function vectors from available behaviors
*/
p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
/*
* Open real time and log devices - order is important.
*/
if (args->logname[0]) {
error = xfs_blkdev_get(mp, args->logname, &logdev);
if (error)
return error;
}
if (args->rtname[0]) {
error = xfs_blkdev_get(mp, args->rtname, &rtdev);
if (error) {
xfs_blkdev_put(logdev);
return error;
}
if (rtdev == ddev || rtdev == logdev) {
cmn_err(CE_WARN,
"XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
xfs_blkdev_put(logdev);
xfs_blkdev_put(rtdev);
return EINVAL;
}
}
µ¥ÀÌÅÍ, ·Î±×, ½Ç½Ã°£ ¼ºê º¼·ý Á¤º¸¸¦ ÃʱâÈÇÑ´Ù. µ¥ÀÌÅÍ ¼ºê º¼·ýÀÇ °æ¿ì¿¡´Â get_sb_bdev() ÇÔ¼ö¿¡¼ ÀÌ¹Ì ÀоîµÎ¾úÀ¸¹Ç·Î ±â¾ïµÈ Á¤º¸¸¦ ¼³Á¤Çϰí, ·Î±× ¼ºê º¼·ý°ú ½Ç½Ã°£ ¼ºê º¼·ýÀÇ °æ¿ì¿¡´Â ¸¶¿îÆ® ¿É¼ÇÀ¸·Î logdev ¿Í rtdev°¡ ÁÖ¾îÁø °æ¿ì¿¡¸¸ ¼³Á¤Çϵµ·Ï ÇÑ´Ù.
´ÙÀ½À¸·Î ¸¶¿îÆ® Á¤º¸¸¦ °¡Áö´Â ±¸Á¶Ã¼¿¡¼ »ç¿ëÇÒ µ¥ÀÌÅÍ °ü¸® ¿¬»ê(m_dm_ops)°ú quota °ü¸® ¿¬»ê(m_qm_ops)°ú IO ¿¬»ê(m_io_ops) Á¤º¸¸¦ ¼³Á¤ÇÑ´Ù. ¸¶¿îÆ®½Ã ¿É¼ÇÀ¸·Î ·Î±× ¼ºê º¼·ý°ú ½Ç½Ã°£ ¼ºê º¼·ýÀÇ À̸§ÀÌ ÁÖ¾îÁø °æ¿ì¿¡´Â ÇØ´çÇÏ´Â ÀåÄ¡¿¡ ´ëÇÑ Á¤º¸¸¦ °¢°¢ logdev¿Í rtdev º¯¼ö¿¡ ÀúÀåÇÑ´Ù. ½Ç½Ã°£ ¼ºê º¼·ýÀÇ °æ¿ì¿¡´Â µ¥ÀÌÅÍ ¼ºê º¼·ýÀ̳ª ·Î±× ¼ºê º¼·ý°ú °°Àº ÀåÄ¡¸¦ »ç¿ëÇÒ ¼ö ¾ø´Ù.
error = ENOMEM;
mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
if (!mp->m_ddev_targp) {
xfs_blkdev_put(logdev);
xfs_blkdev_put(rtdev);
return error;
}
if (rtdev) {
mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
if (!mp->m_rtdev_targp)
goto error0;
}
mp->m_logdev_targp = (logdev && logdev != ddev) ?
xfs_alloc_buftarg(logdev) : mp->m_ddev_targp;
if (!mp->m_logdev_targp)
goto error0;
±×¸®°í °¢°¢ÀÇ ¼ºê º¼·ý¿¡ ´ëÇÑ ¹öÆÛ Ÿ°Ù ±¸Á¶Ã¼¸¦ ÇÒ´çÇÑ´Ù. ·Î±× ¼ºê º¼·ýÀº µ¥ÀÌÅÍ ¼ºê º¼·ý°ú °°ÀÌ »ç¿ëµÉ ¼ö ÀÖÀ¸¹Ç·Î ÀÌ °æ¿ì µ¿ÀÏÇÑ ¹öÆÛ Ÿ°ÙÀ» ÀÌ¿ëÇϵµ·Ï ÇÑ´Ù.
/*
* Setup flags based on mount(2) options and then the superblock
*/
error = xfs_start_flags(vfsp, args, mp);
if (error)
goto error1;
error = xfs_readsb(mp);
if (error)
goto error1;
error = xfs_finish_flags(vfsp, args, mp);
if (error)
goto error2;
¸¶¿îÆ® ½Ã¿¡ ÁÖ¾îÁø ¿É¼ÇµéÀÇ Á¤º¸¸¦ °¡Áö°í ÀÖ´Â args ±¸Á¶Ã¼¸¦ °Ë»çÇÏ¿© ¸¶¿îÆ® ±¸Á¶Ã¼ÀÇ Ç÷¡±× °ªÀ» ¼³Á¤ÇÑ´Ù. ±×¸®°í xfs_readsb() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ½´ÆÛ ºí·°(0¹ø ºí·°)ÀÇ ³»¿ëÀ» Àаí À̸¦ ½´ÆÛ ºí·° ±¸Á¶Ã¼¿¡ ¼³Á¤ÇÑ µÚ ¿Ã¹Ù¸¥ °ªÀ¸·Î ¼³Á¤µÇ¾ú´ÂÁö °Ë»çÇÏ´Â °úÁ¤À» °ÅÃÄ ¸¶¿îÆ® ±¸Á¶Ã¼ÀÇ m_sb_nb Çʵ忡 ÀúÀåÇÑ´Ù.
error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (!error && logdev && logdev != ddev) {
unsigned int log_sector_size = BBSIZE;
if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
log_sector_size = mp->m_sb.sb_logsectsize;
error = xfs_setsize_buftarg(mp->m_logdev_targp,
mp->m_sb.sb_blocksize,
log_sector_size);
}
if (!error && rtdev)
error = xfs_setsize_buftarg(mp->m_rtdev_targp,
mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (error)
goto error2;
error = XFS_IOINIT(vfsp, args, flags);
if (!error)
return 0;
...
}
°¢°¢ÀÇ ¹öÆÛ Ÿ°ÙÀÇ Å©±â¸¦ ¼³Á¤ÇÑ´Ù. µ¥ÀÌÅÍ ¼ºê º¼·ý°ú ½Ç½Ã°£ ¼ºê º¼·ýÀÇ °æ¿ì¿¡´Â ½´ÆÛ ºí·° ±¸Á¶Ã¼¿¡ ÀúÀåµÇ¾î ÀÖ´Â sb_blocksize¿Í sb_sectsize °ªÀ» ÀÌ¿ëÇÏ°í ·Î±× ¼ºê º¼·ýÀÇ °æ¿ì º°µµÀÇ sb_logsectsize °ªÀÌ ÀÖ´Ù¸é À̸¦ ÀÌ¿ëÇϰí, ¾ø´Ù¸é ±âº» ºí·° Å©±âÀÎ BBSIZE(512¹ÙÀÌÆ®)¸¦ »ç¿ëÇϵµ·Ï ÇÑ´Ù. ±×¸®°í XFS_IOINIT() ¸ÅÅ©·Î¸¦ È£ÃâÇϴµ¥ ÀÌ ¸ÅÅ©·Î´Â xfs_mountfs() ÇÔ¼ö¸¦ È£ÃâÇϵµ·Ï Á¤ÀǵǾî ÀÖ´Ù.
xfs_mountfs() ÇÔ¼ö´Â Àоî¿Â ½´ÆÛ ºí·° Á¤º¸·Î ¸¶¿îÆ® ±¸Á¶Ã¼ Á¤º¸¸¦ ¼³Á¤Çϰí 32ºñÆ® Ä¿³ÎÀÎ °æ¿ì Å×¶ó¹ÙÀÌÆ® ´ÜÀ§ÀÇ ÆÄÀÏ ½Ã½ºÅÛÀ» ¸¶¿îÆ®ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. ±×¸®°í ¸¶¿îÆ® ±¸Á¶Ã¼ÀÇ ½Ç½Ã°£ ¼ºê º¼·ý¿¡ °ü·ÃµÈ Á¤º¸µéÀ» ¼³Á¤ÇÑ µÚ ¾ÆÀ̳ëµå ÇØ½Ã Å×À̺íÀ» ¼³Á¤ÇÏ°í µð·ºÅ丮 °ü¸®¸¦ À§ÇÑ ÃʱâÈ ÀÛ¾÷À» ¼öÇàÇÑ´Ù. ¸¶Áö¸·À¸·Î ·Î±× ¸Å´ÏÀú¸¦ ÃʱâÈÇÑ ÈÄ ÇÊ¿äÇÑ °æ¿ì º¹±¸ ·çƾÀ» ¼öÇàÇÑ´Ù.
XFS µ¥¸ó
XFS´Â ±âº»ÀûÀ¸·Î 4 Á¾·ùÀÇ µ¥¸óÀ» ÀÌ¿ëÇÑ´Ù. ÀÌ Áß xfssyncd¿Í xfsbufd µ¥¸óÀº CPUÀÇ ¼ö¿¡ °ü°è¾øÀÌ Çϳª¾¿¸¸ Á¸ÀçÇϰí, xfsdatad¿Í xfslogd µ¥¸óÀº SMP ½Ã½ºÅÛÀÇ °æ¿ì °¢ CPU¸¶´Ù Çϳª¾¿ Á¸ÀçÇÑ´Ù.
¡ß xfssyncd : ¸¶¿îÆ® °úÁ¤ÀÇ linvfs_fill_super() ÇÔ¼ö ³»¿¡¼ linvfs_start_syncd() ÇÔ¼ö¿¡ ÀÇÇØ Ä¿³Î ¾²·¹µå·Î »ý¼ºµÈ´Ù. ½ÇÁ¦ ¼öÇàÇÏ´Â ·çƾÀº <fs/xfs/linux-2.6/xfs_super.c>¿¡ Á¤ÀǵǾî ÀÖ´Â xfssyncd() ÇÔ¼öÀÌ´Ù. ÀÌ ÇÔ¼ö´Â ¹«ÇÑ ·çÇÁ¸¦ µ¹¸ç xfs_syncd_centisecs Áֱ⸶´Ù vfs_sync_worker() ÇÔ¼ö¿¡ ÀÇÇØ xfs_syncsub() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ·Î±× Á¤º¸¿Í ¸ÞŸ µ¥ÀÌÅÍ Á¤º¸µéÀ» ±â·ÏÇÑ´Ù.
¡ß xfsbufd : ÆÄÀÏ ½Ã½ºÅÛ ÃʱâÈ °úÁ¤ÀÇ xfs_fs_init() ÇÔ¼ö ³»¿¡¼ pagebuf_daemon_start() ÇÔ¼ö¿¡ ÀÇÇØ Ä¿³Î ¾²·¹µå·Î »ý¼ºµÈ´Ù. ½ÇÁ¦ ¼öÇàÇÏ´Â ·çƾÀº <fs/xfs/linux-2.6/xfs_buf.c>¿¡ Á¤ÀǵǾî ÀÖ´Â pagebuf_daemon() ÇÔ¼öÀÌ´Ù. ÀÌ ÇÔ¼ö´Â ¹«ÇÑ ·çÇÁ¸¦ µ¹¸ç xfs_buf_timer_centisecs Áֱ⸶´Ù pdb_delwrite_queue ¿¡ µé¾îÀÖ´Â Áö¿¬µÈ ¾²±â ¿¬»ê¿¡ ´ëÇØ pagebuf_iostrategy() ÇÔ¼ö¿Í blk_run_address_space() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© I/O ¿äûÀ» ó¸®ÇÑ´Ù.
¡ß xfsdatad/[cpu], xfslogd/[cpu] : ÆÄÀÏ ½Ã½ºÅÛ ÃʱâÈ °úÁ¤ÀÇ xfs_fs_init() ÇÔ¼ö ³»¿¡¼ pagebuf_daemon_start() ÇÔ¼ö¿¡ ÀÇÇØ Ä¿³Î ¾²·¹µå·Î »ý¼ºµÈ´Ù. ½ÇÁ¦ ¼öÇàÇÏ´Â ·çƾÀº <kernel/workqueue.c> ³»ÀÇ worker_thread() ÇÔ¼öÀÌ´Ù. ÀÌ ÇÔ¼ö´Â set_user_nice() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ÀÚ½ÅÀÇ ¿ì¼±¼øÀ§¸¦ ³ôÀÎ µÚ ¹«ÇÑ ·çÇÁ¸¦ µ¹¸ç ÁÖ¾îÁø ¿öÅ© Å¥¿¡ ¼öÇàÇÒ ÀÛ¾÷ÀÌ µé¾î ÀÖ´Â °æ¿ì run_workqueue() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© À̸¦ ¼öÇàÇÑ´Ù. xfsdatad¿Í xfslogdÀÇ °æ¿ì¿¡´Â °¢°¢ pagebuf_dataio_workqueue ¿Í pagebuf_logio_workqueue¸¦ °ü¸®ÇÑ´Ù.
XFSÀÇ ÆÄÀÏ ¿¬»ê
µ¥ÀÌÅÍ ¿¬»ê
¸®´ª½ºÀÇ °¡»ó ÆÄÀÏ ½Ã½ºÅÛÀÇ ÆÄÀÏ ¿¬»ê ±¸Á¶Ã¼´Â °ü·ÃµÈ ¾ÆÀ̳ëµå¿¡¼ °ü¸®ÇÑ´Ù. XFS¿¡¼ ÀÌ·¯ÇÑ ÆÄÀÏ ¿¬»ê ±¸Á¶Ã¼¸¦ ¼³Á¤ÇÏ´Â °úÁ¤Àº vnode ¿¡ ´ëÇÑ ÃʱâÈ ÇÔ¼ö°¡ ¼öÇàµÇ´Â °úÁ¤¿¡¼ È£ÃâµÇ´Â xfs_set_inodeops() ÇÔ¼ö¿¡¼ ÀÌ·ïÁø´Ù. ÀÌ ÇÔ¼ö´Â <fs/xfs/linux-2.6/xfs_super.c> ÆÄÀÏ¿¡ Á¤ÀǵǾî ÀÖ´Ù.
STATIC __inline__ void
xfs_set_inodeops(
struct inode *inode)
{
vnode_t *vp = LINVFS_GET_VP(inode);
if (vp->v_type == VNON) {
vn_mark_bad(vp);
} else if (S_ISREG(inode->i_mode)) {
inode->i_op = &linvfs_file_inode_operations;
inode->i_fop = &linvfs_file_operations;
inode->i_mapping->a_ops = &linvfs_aops;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &linvfs_dir_inode_operations;
inode->i_fop = &linvfs_dir_operations;
} else if (S_ISLNK(inode->i_mode)) {
inode->i_op = &linvfs_symlink_inode_operations;
if (inode->i_blocks)
inode->i_mapping->a_ops = &linvfs_aops;
} else {
inode->i_op = &linvfs_file_inode_operations;
init_special_inode(inode, inode->i_mode, inode->i_rdev);
}
}
ÀÌ ÇÔ¼ö´Â ÁÖ¾îÁø ¾ÆÀ̳ëµåÀÇ Å¸ÀÔÀ» °Ë»çÇÑ µÚ ±×¿¡ µû¶ó ÀûÀýÇÑ ÆÄÀÏ ¿¬»ê ±¸Á¶Ã¼¸¦ ¼³Á¤ÇÑ´Ù. ÀÏ¹Ý ÆÄÀÏÀÇ °æ¿ì(S_ISREG) ÆÄÀÏ ¿¬»ê ±¸Á¶Ã¼´Â linvfs_file_operations°¡ µÈ´Ù. ÀÌ ±¸Á¶Ã¼´Â <fs/xfs/linux-2.6/xfs_file.c>¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.
struct file_operations linvfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
.readv = linvfs_readv,
.writev = linvfs_writev,
.aio_read = linvfs_read,
.aio_write = linvfs_write,
.sendfile = linvfs_sendfile,
.ioctl = linvfs_ioctl,
.mmap = linvfs_file_mmap,
.open = linvfs_open,
.release = linvfs_release,
.fsync = linvfs_fsync,
};
Àб⠿¬»ê¿¡ ´ëÇØ¼ »ìÆìº¸¸é do_sync_read() ÇÔ¼ö°¡ »ç¿ëµÇ´Â µ¥ ÀÌ ÇÔ¼ö´Â µ¿±âÈ¿¡ °ü·ÃµÈ Á¤º¸µéÀ» ÀûÀýÈ÷ ¼³Á¤ÇÑ µÚ file_operations ±¸Á¶Ã¼ÀÇ aio_read ¸â¹ö°¡ °¡¸®Å°´Â ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. linvfs_read() ÇÔ¼ö´Â ioflags ÀÎÀÚ¸¦ 0À¸·Î ¼³Á¤ÇÏ¿© __linvfs_read() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ÀÌ ÇÔ¼ö´Â <fs/xfs/linux-2.6/xfs_file.c>¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾî ÀÖ´Ù.
STATIC inline ssize_t
__linvfs_read(
struct kiocb *iocb,
char __user *buf,
int ioflags,
size_t count,
loff_t pos)
{
struct iovec iov = {buf, count};
struct file *file = iocb->ki_filp;
vnode_t *vp = LINVFS_GET_VP(file->f_dentry->d_inode);
ssize_t rval;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
return rval;
}
ÀÌ ÇÔ¼ö´Â ÁÖ¾îÁø ÆÄÀÏ¿¡ O_DIRECT Ç÷¡±×°¡ ¼³Á¤µÈ °æ¿ì¿¡ ioflags Ç÷¡±×¿¡ IO_ISDIRECT Ç÷¡±×¸¦ ´õÇÏ¿© VOP_READ() ¸ÅÅ©·Î°¡ °¡¸®Å°´Â read ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ÀÌ °úÁ¤¿¡¼ ÆÄÀÏÀÇ ¾ÆÀ̳ëµå·ÎºÎÅÍ vnode_tÀÇ Á¤º¸¸¦ ÃßÃâÇÏ¿© ¿©±â¿¡ ÀúÀåµÈ vnodeops_t ±¸Á¶Ã¼ÀÇ read ¸â¹ö°¡ °¡¸®Å°´Â xfs_read() ÇÔ¼ö°¡ È£ÃâµÈ´Ù. xfs_read() ÇÔ¼ö´Â <fs/xfs/linux-2.6/xfs_lrw.c> ÆÄÀÏ¿¡ Á¤ÀǵǾî ÀÖ´Ù.
ssize_t /* bytes read, or (-) error */
xfs_read(
bhv_desc_t *bdp,
struct kiocb *iocb,
const struct iovec *iovp,
unsigned int segs,
loff_t *offset,
int ioflags,
cred_t *credp)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
size_t size = 0;
ssize_t ret;
xfs_fsize_t n;
xfs_inode_t *ip;
xfs_mount_t *mp;
vnode_t *vp;
unsigned long seg;
ip = XFS_BHVTOI(bdp);
vp = BHV_TO_VNODE(bdp);
mp = ip->i_mount;
XFS_STATS_INC(xs_read_calls);
xfs_read() ÇÔ¼ö´Â ¿ì¼± ÇÊ¿äÇÑ ±¸Á¶Ã¼¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ¼³Á¤Çϰí, °ü·Ã º¯¼öµéÀ» ¼±¾ðÇÑ µÚ XFS_STATS_INC() ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇÏ¿© Àб⠿¬»êÀÌ ¿äûµÇ¾úÀ½À» ±â·ÏÇÑ´Ù.
for (seg = 0; seg < segs; seg++) {
const struct iovec *iv = &iovp[seg];
size += iv->iov_len;
if (unlikely((ssize_t)(size|iv->iov_len) < 0))
return XFS_ERROR(-EINVAL);
}
if (unlikely(ioflags & IO_ISDIRECT)) {
xfs_buftarg_t *target =
(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
mp->m_rtdev_targp : mp->m_ddev_targp;
if ((*offset & target->pbr_smask) ||
(size & target->pbr_smask)) {
if (*offset == ip->i_d.di_size) {
return (0);
}
return -XFS_ERROR(EINVAL);
}
}
±×¸®°í readv ÇÔ¼ö¿¡ ÀÇÇØ È£ÃâµÈ °æ¿ì±îÁö °í·ÁÇÏ¿© ¿äûµÈ ±¸°£ÀÇ Å©±â°¡ À½¼öÀÎÁö¸¦ °Ë»çÇϰí ÀÌ °æ¿ì ¿¡·¯¸¦ ¸®ÅÏÇÑ´Ù. ±×¸®°í ioflags¿¡ IO_ISDIRECT°¡ ¼³Á¤µÈ °æ¿ì¶ó¸é ÆäÀÌÁö ij½Ã¸¦ °ÅÄ¡Áö ¾Ê°í Á÷Á¢ Àб⠿¬»êÀÌ ¼öÇàµÇ´Â °æ¿ìÀ̹ǷΠÁÖ¾îÁø ¿É¼Â°ú Å©±â°¡ ÇØ´ç µð½ºÅ©ÀÇ ¼½ÅÍ ´ÜÀ§·Î Á¤·ÄµÇ¾î ÀÖ´ÂÁö °Ë»çÇÏ¿© ¿¡·¯¸¦ ¸®ÅÏÇÑ´Ù.
Á¤·ÄµÇ¾î ÀÖÁö ¾ÊÁö¸¸ ¿É¼ÂÀÌ ÆÄÀÏÀÇ Å©±â¿Í °°Àº °æ¿ì¿¡´Â ÆÄÀÏÀÇ ³¡¿¡ µµ´ÞÇÑ °ÍÀ̹ǷΠ´õ ÀÌ»ó ÀÐÀ» µ¥ÀÌÅͰ¡ ¾ø±â ¶§¹®¿¡ ¹Ù·Î 0À» ¸®ÅÏÇÑ´Ù.
n = XFS_MAXIOFFSET(mp) - *offset;
if ((n <= 0) || (size == 0))
return 0;
if (n < size)
size = n;
if (XFS_FORCED_SHUTDOWN(mp)) {
return -EIO;
}
if (unlikely(ioflags & IO_ISDIRECT))
down(&inode->i_sem);
xfs_ilock(ip, XFS_IOLOCK_SHARED);
±×¸®°í ¿É¼Â°ú Àб⠿¬»êÀ» ¼öÇàÇÒ Å©±â¸¦ °Ë»çÇÏ¿© ÀûÀýÈ÷ ¼³Á¤ÇÑ´Ù. ¸¸¾à ÀÌÀü¿¡ ÆÄÀÏ ½Ã½ºÅÛÀÌ °Á¦·Î Á¾·áµÈ ÀûÀÌ ÀÖ¾ú´Ù¸é ÆÄÀÏ ½Ã½ºÅÛ ³»¿¡ ¿Ã¹Ù¸£Áö ¸øÇÑ µ¥ÀÌÅͰ¡ ÀÖÀ» ¼ö ÀÖÀ¸¹Ç·Î Àб⠿¬»êÀº ¹Ù·Î ¿¡·¯¸¦ ¸®ÅÏÇÑ´Ù. ±×·¸Áö ¾Ê´Ù¸é ¾ÆÀ̳ëµå¿¡ ´ëÇÑ °øÀ¯ ¶ôÀ» ȹµæÇÑ´Ù.
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
(void *)iovp, segs, *offset, ioflags);
ret = __generic_file_aio_read(iocb, iovp, segs, offset);
if (ret == -EIOCBQUEUED)
ret = wait_on_sync_kiocb(iocb);
if (ret > 0)
XFS_STATS_ADD(xs_read_bytes, ret);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
if (likely(!(ioflags & IO_INVIS)))
xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
unlock_isem:
if (unlikely(ioflags & IO_ISDIRECT))
up(&inode->i_sem);
return ret;
}
Àб⠿¬»ê¿¡ ´ëÇÑ Æ®·¹À̽º Á¤º¸¸¦ ¹öÆÛ¿¡ Ãß°¡ÇÑ µÚ __generic_file_aio_read() ÇÔ¼ö¸¦ ÅëÇØ ½ÇÁ¦ Àб⠿¬»êÀ» ¼öÇàÇÑ´Ù. __generic_file_aio_read() ÇÔ¼ö´Â ÆÄÀÏ ±¸Á¶Ã¼¿¡ O_DIRECT Ç÷¡±×°¡ ¼³Á¤µÇ¾ú´ÂÁö ¿©ºÎ¿¡ µû¶ó ³»ºÎÀûÀ¸·Î °¢°¢ generic_file_direct_IO() ÇÔ¼ö¿Í do_generic_file_read() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ±×¸®°í ÀÐÀº ¹ÙÀÌÆ® ¼ö¸¦ xs_read_bytes º¯¼ö¿¡ Ãß°¡ÇÏ¿© ±â·ÏÇÑ µÚ °øÀ¯ ¶ôÀ» ÇØÁ¦ÇÏ°í ¾ÆÀ̳ëµåÀÇ Á¢±Ù ½Ã°£À» °»½ÅÇÑ´Ù. ¸¸¾à ioflags¿¡ IO_INVIS Ç÷¡±×°¡ ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì¶ó¸é Á¢±Ù ½Ã°£À» °»½ÅÇÏÁö ¾Ê´Â´Ù.
¾²±â ¿¬»êÀÇ °æ¿ìµµ ´ëü·Î Àб⠿¬»ê°ú ºñ½ÁÇÑ ¼ø¼·Î ÁøÇàµÈ´Ù. vnodeops_t ±¸Á¶Ã¼ÀÇ write Æ÷ÀÎÅÍ´Â xfs_write()¸¦ °¡¸®Å²´Ù. ÀÌ ÇÔ¼öµµ <fs/xfs/linux-2.6/xfs_lrw.c>¿¡ Á¤ÀǵǾî ÀÖ´Ù. °£·«È÷ ¼³¸íÇÏÀÚ¸é ¸ÕÀú xfs_read()¿Í ¸¶Âù°¡Áö·Î ¾²±â ¿¬»êÀÌ È£ÃâµÇ¾úÀ½À» ±â·ÏÇÑ ÈÄ¿¡ writev È£Ãâ¿¡ ÀÇÇÑ °¢°¢ÀÇ iovecÀÇ ¼¼±×¸ÕÆ®¿¡ ´ëÇØ ¾²±â ¿¬»êÀÇ Å©±â¿Í ¹üÀ§¸¦ °Ë»çÇÏ¿© ¿Ã¹Ù¸¥ ÀÎÀÚ¸¸À» °¡·Á³½´Ù. ±×¸®°í ÆÄÀÏ Æ÷ÀÎÅÍ¿Í ¾²±â ¿¬»êÀ» ¼öÇàÇÒ Å©±â °ªÀ» Á¶Á¤ÇÑ µÚ ÀÌÀü¿¡ ÆÄÀÏ ½Ã½ºÅÛÀÌ °Á¦·Î Á¾·áµÇ¾ú´ÂÁö¸¦ °Ë»çÇÏ¿© ÀÌ °æ¿ì ¿¡·¯¸¦ ¸®ÅÏÇϵµ·Ï ÇÑ´Ù.
¶ÇÇÑ IO_ISDIRECT Ç÷¡±×°¡ ¼³Á¤µÈ °æ¿ì¿¡ ¿äûµÈ ¿É¼Â°ú Å©±â°¡ ¼½ÅÍ ´ÜÀ§·Î Á¤·ÄµÇ¾ú´ÂÁö °Ë»çÇÏ°í ¾ÆÀ̳ëµå¿¡ ´ëÇÑ ¼¼¸¶Æ÷¾î ¿¬»êÀ̳ª ÆäÀÌÁö ij½Ã¿¡ ´ëÇÑ flush ¿¬»êÀÌ ÇÊ¿äÇÑÁö¸¦ üũÇÑ´Ù. ±×¸®°í ¾ÆÀ̳ëµå¿¡ ´ëÇÑ ¹èŸÀû ¶ôÀ» ȹµæÇÑ µÚ generic_write_checks() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ¾²±â ¿¬»êÀÌ ¿Ã¹Ù¸¥Áö¸¦ °Ë»çÇϰí(IO_INVIS Ç÷¡±×°¡ ¼³Á¤µÇÁö ¾ÊÀº °æ¿ì) ÆÄÀÏ Á¢±Ù ½Ã°£À» °»½ÅÇÑ´Ù.
ssize_t /* bytes written, or (-) error */
xfs_write(
bhv_desc_t *bdp,
struct kiocb *iocb,
const struct iovec *iovp,
unsigned int nsegs,
loff_t *offset,
int ioflags,
cred_t *credp)
{
...
if (pos > isize) {
error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos,
isize, pos + count);
if (error) {
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
goto out_unlock_isem;
}
}
xfs_iunlock(xip, XFS_ILOCK_EXCL);
if (((xip->i_d.di_mode & S_ISUID) ||
((xip->i_d.di_mode & (S_ISGID | S_IXGRP)) ==
(S_ISGID | S_IXGRP))) &&
!capable(CAP_FSETID)) {
error = xfs_write_clear_setuid(xip);
if (likely(!error))
error = -remove_suid(file->f_dentry);
if (unlikely(error)) {
xfs_iunlock(xip, iolock);
goto out_unlock_isem;
}
}
±×¸®°í ¾²±â ¿¬»êÀÌ ÇöÀç ÆÄÀÏÀÇ Å©±â¸¦ º¯°æÇÏ´Â °æ¿ì¿¡´Â »õ·Î ÇÒ´çµÇ´Â ¿µ¿ª¿¡ ´ëÇØ xfs_zero_eof() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© 0À¸·Î ÃʱâÈÇÑ´Ù. ±×¸®°í ¹èŸÀû ¶ôÀ» ÇØÁ¦ÇÑ µÚ ·çÆ®·Î ½ÇÇàµÇ´Â °æ¿ì°¡ ¾Æ´Ï¶ó¸é ÆÄÀÏÀÇ setuid ºñÆ®¸¦ Á¦°ÅÇÏ¿© ½ÇÇà ÆÄÀÏÀÇ setuid, setgid ºñÆ®¸¦ º¯°æÇÏÁö ¸øÇϵµ·Ï ¹æÁöÇÑ´Ù.
retry:
/* We can write back this queue in page reclaim */
current->backing_dev_info = mapping->backing_dev_info;
if ((ioflags & IO_ISDIRECT)) {
if (need_flush) {
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)),
-1, FI_REMAPF_LOCKED);
}
if (need_isem) {
up(&inode->i_sem);
need_isem = 0;
}
xfs_rw_enter_trace(XFS_DIOWR_ENTER, io, (void *)iovp, segs,
*offset, ioflags);
ret = generic_file_direct_write(iocb, iovp,
&segs, pos, offset, count, ocount);
} else {
xfs_rw_enter_trace(XFS_WRITE_ENTER, io, (void *)iovp, segs,
*offset, ioflags);
ret = generic_file_buffered_write(iocb, iovp, segs,
pos, offset, count, ret);
}
current->backing_dev_info = NULL;
ioflags¿¡ IO_ISDIRECT Ç÷¡±×°¡ ¼³Á¤µÈ °æ¿ì¶ó¸é need_flush, need_isem °ª¿¡ µû¶ó ÀûÀýÇÑ Ã³¸®¸¦ ÇÑ µÚ, generic_file_direct_write() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© Á÷Á¢ ¾²±â ¿¬»êÀ» ¼öÇàÇÑ´Ù. ±×·¸Áö ¾Ê´Ù¸é generic_file_buffered_write() ÇÔ¼ö¸¦ ÅëÇØ ÆäÀÌÁö ij½Ã¸¦ ÀÌ¿ëÇÑ ¾²±â ¿¬»êÀ» ¼öÇàÇÑ´Ù. ±×¸®°í ÆÄÀÏÀÇ Å©±â°¡ º¯°æµÈ °æ¿ì ¾ÆÀ̳ëµå¿¡ ÀÖ´Â ÆÄÀÏ Å©±â °ªÀ» º¯°æÇÏ°í ¾´ ¹ÙÀÌÆ® ¼ö¸¦ xs_write_bytes º¯¼ö¿¡ Ãß°¡ÇÏ¿© ±â·ÏÇÑ´Ù.
if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
!(xip->i_update_size)) {
xfs_inode_log_item_t *iip = xip->i_itemp;
if (iip && iip->ili_last_lsn) {
xfs_log_force(mp, iip->ili_last_lsn,
XFS_LOG_FORCE | XFS_LOG_SYNC);
} else if (xfs_ipincount(xip) > 0) {
xfs_log_force(mp, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
}
} else {
xfs_trans_t *tp;
tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
if ((error = xfs_trans_reserve(tp, 0,
XFS_SWRITE_LOG_RES(mp),
0, 0, 0))) {
/* Transaction reserve failed */
xfs_trans_cancel(tp, 0);
} else {
/* Transaction reserve successful */
xfs_ilock(xip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, xip);
xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(xip, XFS_ILOCK_EXCL);
if (error)
goto out_unlock_internal;
}
}
xfs_rwunlock(bdp, locktype);
if (need_isem)
up(&inode->i_sem);
error = sync_page_range(inode, mapping, pos, ret);
if (!error)
error = ret;
return error;
}
out_unlock_internal:
xfs_rwunlock(bdp, locktype);
out_unlock_isem:
if (need_isem)
up(&inode->i_sem);
return -error;
}
ÆÄÀÏÀ̳ª ¾ÆÀ̳ëµå¿¡ O_SYNC Ç÷¡±×°¡ ¼³Á¤µÇ¾î ÀÖ´Ù¸é ·Î±×¸¦ °°ÀÌ ±â·ÏÇÑ´Ù. ¸¶¿îÆ® ½Ã¿¡ osyncisosync ¿É¼ÇÀÌ ÁÖ¾îÁöÁö ¾Ê¾Ò°í ÆÄÀÏÀÇ Å©±â°¡ º¯ÇÏÁö ¾Ê¾Ò´Ù¸é xfs_log_force() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ¾ÆÀ̳ëµå¿¡ ´ëÇÑ ·Î±×¸¦ ¸ðµÎ ±â·ÏÇÑ´Ù.
ÆÄÀÏ Å©±â°¡ º¯ÇÑ °æ¿ì¿¡´Â Æ®·£Àè¼Ç ±¸Á¶Ã¼¸¦ »ý¼ºÇÏ¿© ¾ÆÀ̳ëµå°¡ º¯°æµÇ¾úÀ½À» µî·ÏÇÏ¿© ½Ã°£ Á¤º¸¸¦ °»½ÅÇϵµ·Ï ·Î±×¸¦ ±â·ÏÇÑ´Ù. ±×¸®°í sync_page_range() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ÆäÀÌÁö ij½ÃÀÇ µ¥ÀÌÅ͸¦ µð½ºÅ©¿¡ ±â·ÏÇÑ´Ù.
Æ®·£Àè¼Ç °ü¸®
Æ®·£Àè¼ÇÀº ·Î±× °ü¸® Äڵ忡 ÀÇÇØ Á¦°øµÇ´Â ±â´ÉÀ» ÀÌ¿ëÇÏ¿© ±ò²ûÇϰí È¿À²ÀûÀÎ Àú³Î¸µ ¸ÞÄ«´ÏÁòÀ» Á¦°øÇÑ´Ù. XFSÀÇ Æ®·£Àè¼Ç °ü¸®´Â µð½ºÅ© ij½Ã, ¾ÆÀ̳ëµå °ü¸®, ·Î±× °ü¸® ÀÎÅÍÆäÀ̽ºÀÇ »óÀ§ °èÃþ¿¡¼ ÀÌ·ç¾îÁö¸ç ÆÄÀÏ ½Ã½ºÅÛÀÇ ¸ÞŸ µ¥ÀÌÅÍ´Â ¹°·Ð »ç¿ëÀÚ µ¥ÀÌÅÍ¿¡µµ Àû¿ëµÈ´Ù. XFSÀÇ Æ®·£Àè¼Ç °ü¸®°¡ ÁøÇàµÇ´Â ¼ø¼´Â ´ÙÀ½°ú °°´Ù.
[1] alloc - ±¸Á¶Ã¼¿Í Æ®·£Àè¼Ç ID »ý¼º : Æ®·£Àè¼Ç ±¸Á¶Ã¼ÀÇ »ý¼ºÀº xfs_trans_alloc() ÇÔ¼ö°¡ ´ã´çÇϴµ¥ ÀÌ ÇÔ¼ö´Â ÆÄÀÏ ½Ã½ºÅÛÀÌ freeze µÇ¾î ÀÖ´ÂÁö °Ë»çÇÑ ÈÄ¿¡ Æ®·£Àè¼ÇÀÇ Ä«¿îÆ® °ªÀ» Áõ°¡½Ã۰í _xfs_trans_alloc() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ÀÌ ÇÔ¼ö´Â xfs_trans_zone ±¸Á¶Ã¼¸¦ ÇÒ´ç¹Þ¾Æ ÀûÀýÈ÷ ÃʱâÈÇÑ´Ù.
[2] reserve - ·Î±× °ø°£ È®º¸(µ¥µå¶ô ¹æÁö) : xfs_trans_reserve() ÇÔ¼ö´Â ·Î±×¸¦ À§ÇÑ °ø°£À¸·Î ÀÎÀÚ·Î ÁÖ¾îÁø logspace * logcount ¸¸ÅÀÇ °ø°£À» È®º¸ÇÑ´Ù. Æ®·£Àè¼ÇÀÌ ÁøÇàµÇ´Â µ¿¾È ·Î±× ¿¬»ê¿¡ ÇÊ¿äÇÑ °ø°£ÀÌ ºÎÁ·ÇÏ°Ô µÇ¸é µ¥µå¶ô¿¡ ºüÁú ¼ö ÀÖÀ¸¹Ç·Î Ç×»ó ¸ðµç ·Î±× ¿¬»êÀÌ ¼öÇàµÉ ¼ö ÀÖ´Â ÃæºÐÇÑ °ø°£ÀÌ È®º¸µÇ¾î¾ß ÇÑ´Ù.
[3] lock - ÀÚ¿ø¿¡ ´ëÇÑ ¶ô ȹµæ : two-phase lockingÀÇ °³³äÀ» µµÀÔÇÏ¿© °ü·ÃµÈ ÀÚ¿ø¿¡ ´ëÇÑ ¶ôÀ» ȹµæÇÑ´Ù. ȹµæÇÑ ¶ôÀº ¸ðµç ¿¬»êÀÌ ³¡³ª°í Æ®·£Àè¼ÇÀÌ Ä¿¹ÔµÇ±â Àü¿¡ ÇØÁ¦µÇ¾î¼´Â ¾È µÈ´Ù.
[4] modify - µ¥ÀÌÅÍ º¯°æ : ½ÇÁ¦·Î ÀÛ¾÷ÇϰíÀÚ ÇÏ´Â ÀÚ¿øÀÇ µ¥ÀÌÅ͸¦ º¯°æÇÑ´Ù. º¯°æ »çÇ×Àº ÀÌÈÄ¿¡ ·Î±×·Î ±â·ÏÇϱâ À§ÇØ ±â¾ïÇØ¾ß ÇÑ´Ù. ÀÌ ´Ü°è¿¡¼ ¿ÀÆÛ·¹ÀÌ¼Ç ·Î±ëÀ» À§ÇÑ Æ®·£Àè¼Ç ¿ÀÆÛ·¹ÀÌ¼Ç ±¸Á¶Ã¼¸¦ »ý¼ºÇÒ ¼ö ÀÖ´Ù.
[5] commit - ·Î±× Á¤º¸¸¦ ¸Þ¸ð¸®¿¡ ±â·Ï : xfs_trans_commit() ÇÔ¼ö´Â º¯°æ »çÇ×°ú Æ®·£Àè¼Ç ¿ÀÆÛ·¹À̼ÇÀ» in-core log(¸Þ¸ð¸®)¿¡ ±â·ÏÇÑ´Ù. ÀÌ ´Ü°è¿¡¼ º¯°æµÈ ÀÚ¿øÀº pinµÇ¾ú´Ù°í Çϸç ÇØ´ç ÀÚ¿ø¿¡ ´ëÇÑ ¶ôÀ» ÇØÁ¦ÇÑ´Ù. ÇöÀç Æ®·£Àè¼ÇÀÇ Á¤º¸´Â ¾ÆÁ÷ µð½ºÅ©¿¡ ±â·ÏµÇÁö ¾ÊÀº »óÅÂÀ̹ǷΠ¿µ±¸ÀûÀÌÁö ¾Ê´Ù.
[6] log - ·Î±× Á¤º¸¸¦ µð½ºÅ©¿¡ ±â·Ï : ¸Þ¸ð¸® ³»ÀÇ in-core log Á¤º¸¸¦ µð½ºÅ© »ó¿¡ ¿µ±¸ÀûÀ¸·Î ±â·ÏÇÏ´Â °úÁ¤ÀÌ´Ù. À̰ÍÀº Æ®·£Àè¼ÇÀ» ¼öÇàÇÏ´Â ·çƾ ³»¿¡¼ Á÷Á¢ ó¸®Çϰųª ȤÀº xfs_trans_set_sync() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© XFS_TRANS_SYNC Ç÷¡±×¸¦ ¼³Á¤Çϰí xfs_trans_commit() ÇÔ¼öÀÇ È£Ãâ °úÁ¤¿¡¼ °£Á¢ÀûÀ¸·Î ó¸®Çϵµ·Ï ÇÒ ¼ö ÀÖ´Ù. ÀÌ °úÁ¤ÀÌ ³¡³ª¸é Æ®·£Àè¼Ç ±¸Á¶Ã¼ Á¤º¸°¡ ÇØÁ¦µÇ°í ÀÚ¿øÀº unpinned »óŰ¡ µÈ´Ù. Æ®·£Àè¼Ç ³»¿¡¼ º¯°æµÈ µ¥ÀÌÅͳª ¿ÀÆÛ·¹ÀÌ¼Ç ·Î±ë Á¤º¸µéÀ» AIL(Active Item List)¿¡ ÀúÀåÇÑ´Ù. ÀÌ ¸®½ºÆ®´Â Æ®·£Àè¼ÇÀ̳ª ·Î±ë °úÁ¤¿¡¼ ·Î±× ³»ÀÇ À¯È¿ÇÑ µ¥ÀÌÅÍÀÇ À§Ä¡¸¦ ã±â À§ÇØ »ç¿ëµÈ´Ù.
[7] flush - µ¥ÀÌÅÍ º¯°æ »çÇ×À» µð½ºÅ©¿¡ ±â·Ï : ·Î±× Á¤º¸°¡ µð½ºÅ©¿¡ ±â·ÏµÇ°í ÀÚ¿øÀÌ unpinned µÇ¾úÀ¸¹Ç·Î ÇØ´ç ÀÚ¿øÀÇ º¯°æ »çÇ×À» µð½ºÅ©¿¡ ±â·ÏÇÑ´Ù. º¯°æµÈ ÀÚ¿øÀÌ µð½ºÅ©¿¡ ±â·ÏµÇ¸é ÀÚµ¿À¸·Î AIL¿¡¼ Á¦°ÅµÈ´Ù. ÀÌÈÄ¿¡ ÇØ´ç ÀÚ¿øÀº »õ·Î¿î Æ®·£Àè¼ÇÀ» À§ÇØ Àç»ç¿ëµÉ ¼ö ÀÖ´Ù.
·Î±× °ü¸®
·Î±× °ü¸® ¼ºñ½º´Â ÆÄÀÏ ½Ã½ºÅÛÀÌ ¼Õ»óµÇ°í ³ ÈÄ¿¡ ½Å¼ÓÇÏ°í ½Å·Ú¼º ÀÖ´Â º¹±¸ ¸ÞÄ«´ÏÁòÀ» Á¦°øÇϱâ À§ÇØ »ç¿ëµÇ¸ç ÆÄÀÏ ½Ã½ºÅÛ ¸ÞŸ µ¥ÀÌÅ͸¦ º¯°æÇÏ´Â ¿¬»ê¿¡ ´ëÇØ ´õ ³ôÀº ¼º´ÉÀ» Á¦°øÇÑ´Ù. XFS´Â ·Î±× Á¤º¸¸¦ ±â·ÏÇϱâ À§ÇÑ º°µµÀÇ ¼ºê º¼·ýÀ» »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç ÀÌ´Â ¸¶¿îÆ® ±¸Á¶Ã¼ÀÇ m_logdev Çʵ忡¼ À¯ÁöÇÑ´Ù. °í¼öÁØÀÇ °üÁ¡¿¡¼ µð½ºÅ© »óÀÇ ·Î±× Á¤º¸´Â ¿øÇü Å¥ÀÇ ÇüÅÂÀÌ´Ù.
Æ®·£Àè¼ÇÀÌ ¼öÇàµÉ ¶§ Æ®·£Àè¼ÇÀ» ¼öÇàÇϴ Ŭ¶óÀÌ¾ðÆ®´Â Æ®·£Àè¼Ç °ü¸®ÀÚ¿¡°Ô Æ®·£Àè¼Ç ¾ÆÀ̵𸦠¿äûÇÑ´Ù. Æ®·£Àè¼Ç ¾ÆÀ̵ð´Â UUID(Universal Unique IDentifier)À̸ç, Æ®·£Àè¼Ç °ü¸®Àڴ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Æ®·£Àè¼Ç ¾ÆÀ̵𸦠¸®ÅÏÇϱâ Àü¿¡ ·Î±× °ü¸®ÀÚ¿¡°Ô Æ®·£Àè¼ÇÀÌ ½ÃÀ۵ǾúÀ½À» ¾Ë¸®´Â ·Î±× Á¤º¸¸¦ º¸³½´Ù. Ŭ¶óÀÌ¾ðÆ®´Â ¿¬»ê¿¡ °ü·ÃµÈ ·Î±× Á¤º¸¸¦ TID¿Í ÇÔ²² ·Î±× °ü¸®ÀÚ¿¡°Ô Á÷Á¢ º¸³½´Ù.
Æ®·£Àè¼ÇÀÌ ¿Ï·áµÇ¸é Ŭ¶óÀÌ¾ðÆ®´Â ·Î±× °ü¸®ÀÚ¸¦ È£ÃâÇÏ¿© Æ®·£Àè¼ÇÀÌ Á¾·áµÇ¾úÀ½À» ¾Ë¸°´Ù. Æ®·£Àè¼ÇÀÇ ÇüÅ¿¡ µû¶ó commit ¿¬»êÀº Æ®·£Àè¼Ç¿¡ °ü·ÃµÈ ¸ÞŸ µ¥ÀÌÅÍ Á¤º¸µéÀÌ µð½ºÅ©¿¡ ±â·ÏµÉ ¶§±îÁö ºí·°µÇ°Å³ª ÄÝ¹é ¸ÞÄ«´ÏÁòÀ» ÀÌ¿ëÇÏ¿© ºñµ¿±âÀûÀ¸·Î ó¸®ÇÑ´Ù.
½Ã½ºÅÛÀÌ ¼Õ»óµÇ¸é ·Î±× °ü¸®ÀÚ´Â µð½ºÅ© »óÀÇ ·Î±× Á¤º¸¸¦ ÀÐ¾î ¸Ç ¸¶Áö¸· ·Î±× Á¤º¸¿Í ¼Õ»óµÇÁö ¾ÊÀº ¸¶Áö¸· Á¤º¸¸¦ Á¶»çÇÑ µÚ ÀÌÈÄÀÇ ·Î±×¸¦ ÀÐ¾î¼ ¼Õ»óµÈ ºÎºÐÀ» À绡¸® º¹±¸ÇÑ´Ù. ÀÌ °úÁ¤Àº <fs/xfs/xfs_log_recover.c>¿¡ ÀÖ´Â xlog_recover() ÇÔ¼ö¿¡ ÀÇÇØ ¼öÇàµÇ´Âµ¥ ¸ÕÀú xlog_find_tail() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© µð½ºÅ©¿Í µ¿±âÈ µÈ ¸¶Áö¸· ·Î±× ·¹ÄÚµåÀÇ À§Ä¡¸¦ ¾Ë¾Æ³½´Ù(<±×¸² 4>ÀÇ °úÁ¤ 0).
ÀÌ Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© ½ÇÁ¦ º¹±¸ ¿¬»êÀ» ¼öÇàÇÒ xlog_do_log_recovery() ÇÔ¼ö¸¦ È£ÃâÇϴµ¥ ÀÌ °úÁ¤Àº µ¿±âȵÇÁö ¾ÊÀº ·Î±× Á¤º¸¸¦ µÎ ¹ø Ž»öÇÏ¿© ¼öÇàµÈ´Ù. ù ¹øÂ° Ž»ö °úÁ¤¿¡¼´Â XLOG_RECOVER_PASS1 ÀÎÀÚ¿Í ÇÔ²² xlog_do_recovery_pass() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© Ãë¼ÒµÈ ·Î±× ¾ÆÀÌÅÛ Á¤º¸¸¦ Àоî(<±×¸² 4>ÀÇ °úÁ¤ 1) À̸¦ xfs_buf_cancel_t ±¸Á¶Ã¼¿¡ ÀúÀåÇÑ´Ù. µÎ ¹øÂ° Ž»ö °úÁ¤¿¡¼´Â XLOG_RECOVER_PASS2 ÀÎÀÚ¿Í ÇÔ²² xlog_do_recovery_pass() ÇÔ¼ö°¡ È£ÃâµÇ¾î xfs_buf_cancel_t ±¸Á¶Ã¼¿¡ ÀúÀåµÈ ¾ÆÀÌÅÛµéÀ» ÀÌ¿ëÇÏ¿© µ¥ÀÌÅ͸¦ º¹±¸ÇÑ´Ù(<±×¸² 4>ÀÇ °úÁ¤ 2).
 |
| <±×¸² 4> ·Î±× Á¤º¸¸¦ ÀÌ¿ëÇÑ ½Ã½ºÅÛ º¹±¸ °úÁ¤ |
XFSÀÇ È®Àå ±â´É
64ºñÆ® ÁÖ¼Ò °ø°£ Áö¿ø
XFS´Â Ä¿³Î ·¹º§¿¡¼ Áö¿øÇÏ´Â 64ºñÆ® ȣȯ ÀÎÅÍÆäÀ̽º¸¦ »ç¿ëÇϹǷΠ32ºñÆ® ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼µµ Åõ¸íÇÏ°Ô 64 ºñÆ® ÆÄÀÏ¿¡ Á¢±ÙÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. À̸¦ À§ÇØ <fs/xfs/xfs_typs.h> ÆÄÀÏ¿¡´Â ½Ã½ºÅÛÀÇ ±âº» Å©±â¿¡ µû¶ó »ç¿ëÇÒ ¼ö ÀÖ´Â °¢Á¾ ŸÀÔµéÀ» Á¤ÀÇÇÑ´Ù.
ºí·° µð¹ÙÀ̽º ·¹À̾¼ 64ºñÆ® ÁÖ¼Ò¸¦ Áö¿øÇÒ ¶§ (CONFIG_LBD) XFS º¼·ýÀÇ ÃÖ´ë Å©±â(ÃÖ´ë ÆÄÀÏ Å©±â)´Â 900¸¸ Å×¶ó¹ÙÀÌÆ®±îÁö Áö¿øµÈ´Ù. 32ºñÆ® Ç÷§Æû¿¡¼ 2.6 Ä¿³ÎÀ» »ç¿ëÇÏ´Â °æ¿ì ºí·° µð¹ÙÀ̽º ·¹À̾¼ 64ºñÆ® ÁÖ¼Ò¸¦ Áö¿øÇÑ´Ù°í ÇØµµ ÆÄÀÏ ½Ã½ºÅÛÀÇ ÃÖ´ë Å©±â¿Í ÆÄÀÏÀÇ ÃÖ´ë Å©±â´Â 16Å×¶ó¹ÙÀÌÆ®·Î Á¦ÇѵȴÙ.
DMAPI - HSM Áö¿ø
HSM(Hierachical Storage Management)Àº °ª½Î°í ´À¸° ÀúÀå ÀåÄ¡¿Í ºñ½Î°í ºü¸¥ ÀúÀå ÀåÄ¡µéÀ» °èÃþÀûÀ¸·Î °ü¸®ÇÏ¿© ÁÖ·Î »ç¿ëÇÏ´Â µ¥ÀÌÅÍ µéÀ» º¸´Ù ºü¸¥ ÀúÀå ÀåÄ¡¿¡ ÀúÀåÇÔÀ¸·Î½á ºñ¿ë°ú ¼º´É »óÀÇ ÀÌÁ¡À» ²ÒÇϰíÀÚ ÇÏ´Â °³³äÀÌ´Ù. ÀÌ»óÀûÀ¸·Î ¸ðµç ÀúÀå ÀåÄ¡°¡ ºü¸¥ Á¢±Ù ¼Óµµ¸¦ ³»´Â °ÍÀÌ °¡Àå ÁÁÁö¸¸ ±×·¸°Ô Çϱâ À§Çؼ´Â ¸·´ëÇÑ ºñ¿ëÀÌ ¼Ò¿äµÇ¹Ç·Î Çö½ÇÀûÀÎ ÀÌÀ¯·Î ´À¸®Áö¸¸ °ª½Ñ ÀúÀå ÀåÄ¡¸¦ ¸¹ÀÌ »ç¿ëÇÏ´Â µ¥¿¡¼ ºñ·ÔµÈ °ÍÀÌ´Ù. °£´ÜÈ÷, ¸Þ¸ð¸® °ü¸®¿¡¼Ã³·³ ÀúÀå ÀåÄ¡ÀÇ °ü¸®¿¡ À־µ ij½Ã¸¦ µµÀÔÇÑ °ÍÀ̶ó°í »ý°¢ÇÒ ¼ö ÀÖ´Ù.
XFS´Â DMAPI¸¦ ÅëÇØ Ä¿³ÎÀÇ ¼öÁ¤ ¾øÀÌ HSM ¼ÒÇÁÆ®¿þ¾î¸¦ ±¸ÇöÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. DMAPI(ȤÀº XDSM)´Â X/Open ¹®¼ÀÎ <Systems Management: Data Storage Management (XDSM) API>ÀÇ ±¸ÇöÀÌ´Ù. XFS¿¡¼ libdm ¶óÀ̺귯¸®¸¦ ÅëÇØ DMAPI ÀÎÅÍÆäÀ̽º¸¦ Á¦°øÇÏ´Â ÇÔ¼ö¸¦ µî·ÏÇÒ ¼ö ÀÖÀ¸¸ç SGIÀÇ DMF, VeritasÀÇ Veritas HSM µîÀÌ À̸¦ Áö¿øÇÑ´Ù.
½Ç½Ã°£ ¼ºê º¼·ý
XFS´Â ½Ç½Ã°£ µ¥ÀÌÅ͸¦ ÀúÀåÇϱâ À§ÇÑ ½Ç½Ã°£ ¼ºê º¼·ýÀ» ¿É¼ÇÀ¸·Î Á¦°øÇÑ´Ù. ½Ç½Ã°£ ¼ºê º¼·ýÀº ÀϹÝÀûÀÎ B+ Æ®¸®·Î ±¸ÇöµÈ ÇÒ´çÀÚ°¡ ¾Æ´Ñ ºñÆ®¸ÊÀ» ÀÌ¿ëÇÑ ½Ç½Ã°£ ÇÒ´çÀÚ°¡ »ç¿ëµÈ´Ù. ÀÌ·¯ÇÑ ½Ç½Ã°£ ¼ºê º¼·ýÀº ¸ÖƼ¹Ìµð¾î ½ºÆ®¸®¹Ö ÀÀ¿ë ÇÁ·Î±×·¥°ú °°ÀÌ ½Å·ÚÇÒ ¸¸ÇÑ µ¥ÀÌÅÍ Àü¼Û·üÀ» º¸ÀåÇØ¾ß ÇÏ´Â ¿µ¿ª¿¡¼ À¯¿ëÇÏ°Ô »ç¿ëµÉ ¼ö ÀÖ´Ù.
½Ç½Ã°£ ¼ºê º¼·ýÀÇ °ø°£ ÇÒ´çÀº <fs/xfs/xfs_rtalloc.c> ¿¡ Á¤ÀÇµÈ xfs_rtallocate_extent() ÇÔ¼ö¿¡¼ ¼öÇàµÇ¸ç ÁÖ¾îÁø ÇÒ´ç ŸÀÔ¿¡ µû¶ó °¢°¢ xfs_rtallocate_extent_size(), xfs_rtallocate_extent_near, xfs_rtallocate_extent_exact() ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. XFS¿¡¼ ÇÒ´ç ½Ã ¿äûÇÒ ¼ö ÀÖ´Â ÇÒ´ç ŸÀÔÀ» <Ç¥ 2>¿¡ ³ªÅ¸³»¾ú´Ù. ½Ç½Ã°£ ¼ºê º¼·ý¿¡¼´Â ÀÌ Áß 3°¡Áö¸¸ÀÌ »ç¿ëµÈ´Ù.
 |
| <Ç¥ 2> XFSÀÇ ÇÒ´ç ŸÀÔ |
µð½ºÅ© °ø°£ ÇÒ´ç ½Ã¿¡´Â ¿äûÇÏ´Â ½ÇÁ¦ Å©±â Á¤º¸¿Í ÇÔ²² ÃÖ´ë Å©±â¿Í ÃÖ¼Ò Å©±â Á¤º¸°¡ Á¦°øµÇ¾î ¿ì¼± ÃÖ´ë Å©±â¸¸Å ÇÒ´çÀÌ °¡´ÉÇÑÁö °Ë»çÇÏ¿© ºÒ°¡´ÉÇÑ °æ¿ì¿¡ ÃÖ¼Ò Å©±â ÀÌ»óÀÇ °ø°£À» ÇÒ´çÇϵµ·Ï ÇÑ´Ù.
´Ù¸¥ ÆÄÀÏ ½Ã½ºÅÛ ºÐ¼®¿¡ µµ¿òÀÌ µÇ±æ
À̹ø ±Û¿¡¼´Â °í¼º´É Àú³Î¸µ ÆÄÀÏ ½Ã½ºÅÛÀÎ XFS¿¡ ´ëÇØ¼ °£·«È÷ ¾Ë¾Æº¸¾Ò´Ù. Á¦ÇÑµÈ Áö¸é°ú ½Ã°£À¸·Î ÀÎÇØ XFSÀ» ³¹³¹ÀÌ ÆÄÇìÃÄ º¸Áö ¸øÇÑ ¾Æ½¬¿òÀÌ ³²Áö¸¸ ¾î´À Á¤µµ À±°ûÀ» ÀâÀ» ¼ö ÀÖ¾ú±â¸¦ ¹Ù¶ó¸ç ¾ÕÀ¸·Îµµ ´Ù¸¥ ÆÄÀÏ ½Ã½ºÅÛÀ» ºÐ¼®ÇÒ ¶§ µµ¿òÀÌ µÉ ¸¸ÇÑ ÀÚ·á°¡ µÇ±â¸¦ ¹Ù¶õ´Ù. ´ÙÀ½ ¿¬Àç¿¡¼´Â ¸¶Áö¸·À¸·Î ¸®´ª½ºÀÇ ÃÖ´ë ÀåÁ¡ ÁßÀÇ Çϳª·Î ²ÅÈ÷´Â ³×Æ®¿öÅ© ¼ºê ½Ã½ºÅÛ¿¡ ´ëÇØ¼ »ìÆìº¸±â·Î ÇÑ´Ù.@
* ÀÌ ±â»ç´Â ZDNet KoreaÀÇ Á¦ÈÞ¸ÅüÀÎ ¸¶ÀÌÅ©·Î¼ÒÇÁÆ®¿þ¾î¿¡ °ÔÀçµÈ ³»¿ëÀÔ´Ï´Ù.