分三步:1.读磁盘块到缓存,2.拷贝用户缓存到page cache。3.flush缓存
1.读磁盘到缓存
其中包括为文件相应的块分配page cache和bh。分配好缓存以后,先通过ll_rw_block把bio加入请求队列。然后调用wait_on_buffer处理请求(发送SCSI命令)。
request入队调用栈:
#0 generic_make_request (bio=0xc7c64e60) at block/ll_rw_blk.c:3286
#1 0xc0142ad4 in submit_bio (rw=, bio=0xc7c64e60)
at block/ll_rw_blk.c:3384
#2 0xc00a8d6c in submit_bh (rw=0, bh=0xc7806780) at fs/buffer.c:2902
#3 0xc00aa4b8 in ll_rw_block (rw=0, nr=1, bhs=)
at fs/buffer.c:2960
#4 0xc00aaaac in __block_prepare_write (inode=0xc7802a68, page=0xc0455ee0,
from=0, to=512, get_block=0xc00af6f4 )
at fs/buffer.c:1888
#5 0xc00aaca8 in block_write_begin (file=,
mapping=, pos=0, len=512, flags=0, pagep=0xc7cb3d94,
fsdata=0xc7cb3d90, get_block=0xc00af6f4 )
at fs/buffer.c:1976
#6 0xc00ae82c in blkdev_write_begin (file=0x0, mapping=0x0,
pos=6917529109245460484, len=512, flags=0, pagep=0xc7cb3d94,
fsdata=0xc7cb3d90) at fs/block_dev.c:386
#7 0xc006b148 in generic_file_buffered_write (iocb=0xc7cb3e90,
iov=, nr_segs=,
pos=6917529109245460484, ppos=0xc7cb3ee0, count=512, written=0)
at mm/filemap.c:2236
#8 0xc006ba78 in __generic_file_aio_write_nolock (iocb=0xc7cb3e90,
iov=0xc7cb3f20, nr_segs=1, ppos=0xc7cb3ee0) at mm/filemap.c:2415
#9 0xc006bc04 in generic_file_aio_write_nolock (iocb=0x0, iov=0x0, nr_segs=4,
---Type to continue, or q to quit---
pos=0) at mm/filemap.c:2433
#10 0xc0087d20 in do_sync_write (filp=0xc7135220, buf=,
len=, ppos=0xc7cb3f78) at fs/read_write.c:300
#11 0xc00885ec in vfs_write (file=0xc7135220, buf=0x51050 "", count=4,
pos=0xc7cb3f78) at fs/read_write.c:331
#12 0xc0088b98 in sys_write (fd=, buf=0x0, count=4)
at fs/read_write.c:384
读请求处理:
#0 sym53c8xx_queue_command (cmd=0xc74d0ba0, done=0xc01967b4 )
at drivers/scsi/sym53c8xx_2/sym_glue.h:228
#1 0xc0196d64 in scsi_dispatch_cmd (cmd=0xc74d0ba0) at drivers/scsi/scsi.c:567
#2 0xc019c868 in scsi_request_fn (q=0xc74d9b78)
at drivers/scsi/scsi_lib.c:1583
#3 0xc0144128 in __generic_unplug_device (q=0xc74d9b78)
at block/ll_rw_blk.c:1596
#4 0xc014442c in generic_unplug_device (q=0xc74d0ba0)
at block/ll_rw_blk.c:1614
#5 0xc0141820 in blk_unplug (q=0xc74d0ba0) at block/ll_rw_blk.c:1657
#6 0xc0141838 in blk_backing_dev_unplug (bdi=,
page=0xc01967b4) at block/ll_rw_blk.c:1624
#7 0xc00aa12c in sync_buffer (word=)
at include/linux/blkdev.h:711
#8 0xc0276668 in __wait_on_bit (wq=0xc00000d8, q=0xc7cbfc1c,
action=0xc00aa0e4 , mode=2) at kernel/wait.c:169
#9 0xc0276848 in out_of_line_wait_on_bit (word=0xc78064a8, bit=2,
action=0xc00aa0e4 , mode=2) at kernel/wait.c:182
#10 0xc00aa060 in __wait_on_buffer (bh=0xc74d0ba0) at include/linux/wait.h:434
#11 0xc00aab3c in __block_prepare_write (inode=0xc78020a8, page=0xc044a5a0,
from=0, to=512, get_block=0xc00af6f4 )
at include/linux/buffer_head.h:318
#12 0xc00aaca8 in block_write_begin (file=,
---Type to continue, or q to quit---
mapping=, pos=0, len=512, flags=0, pagep=0xc7cbfd94,
fsdata=0xc7cbfd90, get_block=0xc00af6f4 )
at fs/buffer.c:1976
#13 0xc00ae82c in blkdev_write_begin (file=0xc74d0ba0, mapping=0xc01967b4,
pos=-4597233264497786742, len=512, flags=0, pagep=0xc7cbfd94,
fsdata=0xc7cbfd90) at fs/block_dev.c:386
#14 0xc006b148 in generic_file_buffered_write (iocb=0xc7cbfe90,
iov=, nr_segs=,
pos=-4597233264497786742, ppos=0xc7cbfee0, count=512, written=0)
at mm/filemap.c:2236
#15 0xc006ba78 in __generic_file_aio_write_nolock (iocb=0xc7cbfe90,
iov=0xc7cbff20, nr_segs=1, ppos=0xc7cbfee0) at mm/filemap.c:2415
#16 0xc006bc04 in generic_file_aio_write_nolock (iocb=0xc74d0ba0,
iov=0xc01967b4, nr_segs=138, pos=0) at mm/filemap.c:2433
#17 0xc0087d20 in do_sync_write (filp=0xc7c84660, buf=,
len=, ppos=0xc7cbff78) at fs/read_write.c:300
#18 0xc00885ec in vfs_write (file=0xc7c84660, buf=0x51050 "", count=138,
pos=0xc7cbff78) at fs/read_write.c:331
#19 0xc0088b98 in sys_write (fd=, buf=0x0, count=138)
at fs/read_write.c:384
#20 0xc0024e40 in kuser_cmpxchg_fixup ()
2.至此,文件缓存已更新,在generic_perform_write中把用户数据考入page cache.
3.flush缓存
过程如1,只不过这次是写。
请求入队调用栈:
#0 submit_bh (rw=1, bh=0xc7806518)
at include/asm-generic/bitops/non-atomic.h:105
#1 0xc00ab100 in __block_write_full_page (inode=,
page=0xc044aba0, get_block=0xc00af6f4 , wbc=0xc7cb5dd0)
at fs/buffer.c:1712
#2 0xc00ab2f4 in block_write_full_page (page=0xc044aba0,
get_block=0xc00af6f4 , wbc=0xc7cb5dd0)
at fs/buffer.c:2812
#3 0xc00ae870 in blkdev_writepage (page=0x1, wbc=0xc0348d10)
at fs/block_dev.c:373
#4 0xc006fc3c in __writepage (page=0x1, wbc=0xc7806518, data=0xc0348d10)
at mm/page-writeback.c:894
#5 0xc00702b0 in write_cache_pages (mapping=0xc7802b00, wbc=0xc7cb5dd0,
writepage=0xc006fc1c <__writepage>, data=0xc7802b00)
at mm/page-writeback.c:855
#6 0xc0070428 in generic_writepages (mapping=0x12d, wbc=0xc7806518)
at mm/page-writeback.c:914
#7 0xc0070478 in do_writepages (mapping=0xc0348d10, wbc=0xc7806518)
at mm/page-writeback.c:927
#8 0xc006aad0 in __filemap_fdatawrite_range (mapping=0xc7802b00, start=0,
end=9223372036854775807, sync_mode=1) at mm/filemap.c:217
#9 0xc006ad4c in filemap_fdatawrite (mapping=0x1) at mm/filemap.c:224
#10 0xc006ad78 in filemap_write_and_wait (mapping=0xc7802b00)
---Type to continue, or q to quit---
at mm/filemap.c:392
#11 0xc00a9f5c in sync_blockdev (bdev=) at fs/buffer.c:170
#12 0xc00aed88 in __blkdev_put (bdev=0xc7802a00, for_part=0)
at fs/block_dev.c:1288
#13 0xc00aee6c in blkdev_put (bdev=0x1) at fs/block_dev.c:1321
#14 0xc00af8b8 in blkdev_close (inode=, filp=0xc7806518)
at fs/block_dev.c:1330
#15 0xc0088fc4 in __fput (file=0xc7c1f320) at fs/file_table.c:228
#16 0xc0089268 in fput (file=0x1) at fs/file_table.c:203
#17 0xc0085fec in filp_close (filp=0xc7c1f320, id=0xc7c13a40) at fs/open.c:1111
#18 0xc0046fd4 in put_files_struct (files=0xc7c13a40) at kernel/exit.c:440
#19 0xc0047050 in __exit_files (tsk=0xc0348d10) at kernel/exit.c:504
#20 0xc0048354 in do_exit (code=256) at kernel/exit.c:998
#21 0xc00488f8 in do_group_exit (exit_code=1) at kernel/exit.c:1098
#22 0xc0048918 in sys_exit_group (error_code=)
at kernel/exit.c:1109
关闭时刷新缓存,提交SCSI命令到SCSI dev队列。
写命令入队调用栈:
#0 sym53c8xx_queue_command (cmd=0xc74d1cc0, done=0xc01967b4 )
at drivers/scsi/sym53c8xx_2/sym_glue.h:228
#1 0xc0196d64 in scsi_dispatch_cmd (cmd=0xc74d1cc0) at drivers/scsi/scsi.c:567
#2 0xc019c868 in scsi_request_fn (q=0xc74dcb78)
at drivers/scsi/scsi_lib.c:1583
#3 0xc0144128 in __generic_unplug_device (q=0xc74dcb78)
at block/ll_rw_blk.c:1596
#4 0xc014442c in generic_unplug_device (q=0xc74d1cc0)
at block/ll_rw_blk.c:1614
#5 0xc0141820 in blk_unplug (q=0xc74d1cc0) at block/ll_rw_blk.c:1657
#6 0xc0141838 in blk_backing_dev_unplug (bdi=,
page=0xc01967b4) at block/ll_rw_blk.c:1624
#7 0xc00a85a8 in block_sync_page (page=0xc01967b4)
at include/linux/blkdev.h:711
#8 0xc0069cbc in sync_page (word=0xc74d1cc0) at mm/filemap.c:183
#9 0xc0276668 in __wait_on_bit (wq=0xc0000280, q=0xc7cb5d7c,
action=0xc0069c80 , mode=2) at kernel/wait.c:169
#10 0xc006a028 in wait_on_page_bit (page=0xc044ab80, bit_nr=12)
at mm/filemap.c:530
#11 0xc006a958 in wait_on_page_writeback_range (mapping=0xc7802b00,
start=, end=10239) at include/linux/pagemap.h:209
#12 0xc006aa5c in filemap_fdatawait (mapping=)
at mm/filemap.c:382
---Type to continue, or q to quit---
#13 0xc006ad8c in filemap_write_and_wait (mapping=0xc7802b00)
at mm/filemap.c:400
#14 0xc00a9f5c in sync_blockdev (bdev=) at fs/buffer.c:170
#15 0xc00aed88 in __blkdev_put (bdev=0xc7802a00, for_part=0)
at fs/block_dev.c:1288
#16 0xc00aee6c in blkdev_put (bdev=0xc74d1cc0) at fs/block_dev.c:1321
#17 0xc00af8b8 in blkdev_close (inode=, filp=0xc01967b4)
at fs/block_dev.c:1330
#18 0xc0088fc4 in __fput (file=0xc7c1f6a0) at fs/file_table.c:228
#19 0xc0089268 in fput (file=0xc74d1cc0) at fs/file_table.c:203
#20 0xc0085fec in filp_close (filp=0xc7c1f6a0, id=0xc7c13a40) at fs/open.c:1111
#21 0xc0046fd4 in put_files_struct (files=0xc7c13a40) at kernel/exit.c:440
#22 0xc0047050 in __exit_files (tsk=0x8c) at kernel/exit.c:504
#23 0xc0048354 in do_exit (code=256) at kernel/exit.c:998
#24 0xc00488f8 in do_group_exit (exit_code=1) at kernel/exit.c:1098
#25 0xc0048918 in sys_exit_group (error_code=)
at kernel/exit.c:1109