V1->V2 Changes: change the fix method. we split bios in btrfs_submit_direct() to fix this problem now. btrfs paniced when we write >64KB data by direct IO at one time. Reproduce steps: # mkfs.btrfs /dev/sda5 /dev/sda6 # mount /dev/sda5 /mnt # dd if=/dev/zero of=/mnt/tmpfile bs=100K count=1 oflag=direct Then btrfs paniced: mapping failed logical 1103155200 bio len 69632 len 12288 ------------[ cut here ]------------ kernel BUG at fs/btrfs/volumes.c:3010! [SNIP] Pid: 1992, comm: btrfs-worker-0 Not tainted 2.6.37-rc1 #1 D2399/PRIMERGY RIP: 0010:[<ffffffffa03d1462>] [<ffffffffa03d1462>] btrfs_map_bio+0x202/0x210 [btrfs] [SNIP] Call Trace: [<ffffffffa03ab3eb>] __btrfs_submit_bio_done+0x1b/0x20 [btrfs] [<ffffffffa03a35ff>] run_one_async_done+0x9f/0xb0 [btrfs] [<ffffffffa03d3d20>] run_ordered_completions+0x80/0xc0 [btrfs] [<ffffffffa03d45a4>] worker_loop+0x154/0x5f0 [btrfs] [<ffffffffa03d4450>] ? worker_loop+0x0/0x5f0 [btrfs] [<ffffffffa03d4450>] ? worker_loop+0x0/0x5f0 [btrfs] [<ffffffff81083216>] kthread+0x96/0xa0 [<ffffffff8100cec4>] kernel_thread_helper+0x4/0x10 [<ffffffff81083180>] ? kthread+0x0/0xa0 [<ffffffff8100cec0>] ? kernel_thread_helper+0x0/0x10 We fix this problem by splitting bios when we submit bios. Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Tested-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> --- fs/btrfs/inode.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 184 insertions(+), 21 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5a5edc7..c91d0e3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5535,13 +5535,21 @@ struct btrfs_dio_private { u64 bytes; u32 *csums; void *private; + + /* number of bios pending for this dio */ + atomic_t pending_bios; + + /* IO errors */ + int errors; + + struct bio *orig_bio; }; static void btrfs_endio_direct_read(struct bio *bio, int err) { + struct btrfs_dio_private *dip = bio->bi_private; struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; struct bio_vec *bvec = bio->bi_io_vec; - struct btrfs_dio_private *dip = bio->bi_private; struct inode *inode = dip->inode; struct btrfs_root *root = BTRFS_I(inode)->root; u64 start; @@ -5684,6 +5692,176 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, return 0; } +static void btrfs_end_dio_bio(struct bio *bio, int err) +{ + struct btrfs_dio_private *dip = bio->bi_private; + + if (err) { + printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " + "disk_bytenr %lu len %u err no %d\n", + dip->inode->i_ino, bio->bi_rw, bio->bi_sector, + bio->bi_size, err); + dip->errors = 1; + + /* + * before atomic variable goto zero, we must make sure + * dip->errors is perceived to be set. + */ + smp_mb__before_atomic_dec(); + } + + /* if there are more bios still pending for this dio, just exit */ + if (!atomic_dec_and_test(&dip->pending_bios)) + goto out; + + if (dip->errors) + bio_io_error(dip->orig_bio); + else { + set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); + bio_endio(dip->orig_bio, 0); + } +out: + bio_put(bio); +} + +static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, + u64 first_sector, gfp_t gfp_flags) +{ + int nr_vecs = bio_get_nr_vecs(bdev); + return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags); +} + +static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, + int rw, u64 file_offset, int skip_sum, + u32 *csums) +{ + int write = rw & REQ_WRITE; + struct btrfs_root *root = BTRFS_I(inode)->root; + int ret; + + bio_get(bio); + ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); + if (ret) + goto err; + + if (write && !skip_sum) { + ret = btrfs_wq_submit_bio(root->fs_info, + inode, rw, bio, 0, 0, + file_offset, + __btrfs_submit_bio_start_direct_io, + __btrfs_submit_bio_done); + goto err; + } else if (!skip_sum) + btrfs_lookup_bio_sums_dio(root, inode, bio, + file_offset, csums); + + ret = btrfs_map_bio(root, rw, bio, 0, 1); +err: + bio_put(bio); + return ret; +} + +static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, + int skip_sum) +{ + struct inode *inode = dip->inode; + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; + struct bio *bio; + struct bio *orig_bio = dip->orig_bio; + struct bio_vec *bvec = orig_bio->bi_io_vec; + u64 start_sector = orig_bio->bi_sector; + u64 file_offset = dip->logical_offset; + u64 submit_len = 0; + u64 map_length; + int nr_pages = 0; + u32 *csums = dip->csums; + int ret = 0; + + bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); + if (!bio) + return -ENOMEM; + bio->bi_private = dip; + bio->bi_end_io = btrfs_end_dio_bio; + atomic_inc(&dip->pending_bios); + + map_length = orig_bio->bi_size; + ret = btrfs_map_block(map_tree, READ, start_sector << 9, + &map_length, NULL, 0); + if (ret) { + bio_put(bio); + return -EIO; + } + + while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { + if (unlikely(map_length < submit_len + bvec->bv_len || + bio_add_page(bio, bvec->bv_page, bvec->bv_len, + bvec->bv_offset) < bvec->bv_len)) { + /* + * inc the count before we submit the bio so + * we know the end IO handler won''t happen before + * we inc the count. Otherwise, the dip might get freed + * before we''re done setting it up + */ + atomic_inc(&dip->pending_bios); + ret = __btrfs_submit_dio_bio(bio, inode, rw, + file_offset, skip_sum, + csums); + if (ret) { + bio_put(bio); + atomic_dec(&dip->pending_bios); + goto out_err; + } + + if (!skip_sum) + csums = csums + nr_pages; + start_sector += submit_len >> 9; + file_offset += submit_len; + + submit_len = 0; + nr_pages = 0; + + bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, + start_sector, GFP_NOFS); + if (!bio) + goto out_err; + bio->bi_private = dip; + bio->bi_end_io = btrfs_end_dio_bio; + + map_length = orig_bio->bi_size; + ret = btrfs_map_block(map_tree, READ, start_sector << 9, + &map_length, NULL, 0); + if (ret) { + bio_put(bio); + goto out_err; + } + } else { + submit_len += bvec->bv_len; + nr_pages ++; + bvec++; + } + } + + ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, + csums); + if (!ret) + return 0; + + bio_put(bio); +out_err: + dip->errors = 1; + /* + * before atomic variable goto zero, we must + * make sure dip->errors is perceived to be set. + */ + smp_mb__before_atomic_dec(); + if (atomic_dec_and_test(&dip->pending_bios)) + bio_io_error(dip->orig_bio); + + /* bio_end_io() will handle error, so we needn''t return it */ + return 0; +} + static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, loff_t file_offset) { @@ -5723,33 +5901,18 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, dip->disk_bytenr = (u64)bio->bi_sector << 9; bio->bi_private = dip; + dip->errors = 0; + dip->orig_bio = bio; + atomic_set(&dip->pending_bios, 0); if (write) bio->bi_end_io = btrfs_endio_direct_write; else bio->bi_end_io = btrfs_endio_direct_read; - ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); - if (ret) - goto free_ordered; - - if (write && !skip_sum) { - ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, - inode, rw, bio, 0, 0, - dip->logical_offset, - __btrfs_submit_bio_start_direct_io, - __btrfs_submit_bio_done); - if (ret) - goto free_ordered; + ret = btrfs_submit_direct_hook(rw, dip, skip_sum); + if (!ret) return; - } else if (!skip_sum) - btrfs_lookup_bio_sums_dio(root, inode, bio, - dip->logical_offset, dip->csums); - - ret = btrfs_map_bio(root, rw, bio, 0, 1); - if (ret) - goto free_ordered; - return; free_ordered: /* * If this is a write, we need to clean up the reserved space and kill -- 1.7.0.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Chris Mason
2010-Nov-22 03:18 UTC
Re: [PATCH -V2 3/3] btrfs: fix panic caused by direct IO
Great, I''ll test this and the others overnight. Thanks! -chris Excerpts from Miao Xie''s message of 2010-11-21 22:04:43 -0500:> V1->V2 Changes: > change the fix method. we split bios in btrfs_submit_direct() to fix this > problem now. > > btrfs paniced when we write >64KB data by direct IO at one time. > > Reproduce steps: > # mkfs.btrfs /dev/sda5 /dev/sda6 > # mount /dev/sda5 /mnt > # dd if=/dev/zero of=/mnt/tmpfile bs=100K count=1 oflag=direct > > Then btrfs paniced: > mapping failed logical 1103155200 bio len 69632 len 12288 > ------------[ cut here ]------------ > kernel BUG at fs/btrfs/volumes.c:3010! > [SNIP] > Pid: 1992, comm: btrfs-worker-0 Not tainted 2.6.37-rc1 #1 D2399/PRIMERGY > RIP: 0010:[<ffffffffa03d1462>] [<ffffffffa03d1462>] btrfs_map_bio+0x202/0x210 [btrfs] > [SNIP] > Call Trace: > [<ffffffffa03ab3eb>] __btrfs_submit_bio_done+0x1b/0x20 [btrfs] > [<ffffffffa03a35ff>] run_one_async_done+0x9f/0xb0 [btrfs] > [<ffffffffa03d3d20>] run_ordered_completions+0x80/0xc0 [btrfs] > [<ffffffffa03d45a4>] worker_loop+0x154/0x5f0 [btrfs] > [<ffffffffa03d4450>] ? worker_loop+0x0/0x5f0 [btrfs] > [<ffffffffa03d4450>] ? worker_loop+0x0/0x5f0 [btrfs] > [<ffffffff81083216>] kthread+0x96/0xa0 > [<ffffffff8100cec4>] kernel_thread_helper+0x4/0x10 > [<ffffffff81083180>] ? kthread+0x0/0xa0 > [<ffffffff8100cec0>] ? kernel_thread_helper+0x0/0x10 > > We fix this problem by splitting bios when we submit bios. > > Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> > Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> > Tested-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> > --- > fs/btrfs/inode.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++++------ > 1 files changed, 184 insertions(+), 21 deletions(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index 5a5edc7..c91d0e3 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -5535,13 +5535,21 @@ struct btrfs_dio_private { > u64 bytes; > u32 *csums; > void *private; > + > + /* number of bios pending for this dio */ > + atomic_t pending_bios; > + > + /* IO errors */ > + int errors; > + > + struct bio *orig_bio; > }; > > static void btrfs_endio_direct_read(struct bio *bio, int err) > { > + struct btrfs_dio_private *dip = bio->bi_private; > struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; > struct bio_vec *bvec = bio->bi_io_vec; > - struct btrfs_dio_private *dip = bio->bi_private; > struct inode *inode = dip->inode; > struct btrfs_root *root = BTRFS_I(inode)->root; > u64 start; > @@ -5684,6 +5692,176 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, > return 0; > } > > +static void btrfs_end_dio_bio(struct bio *bio, int err) > +{ > + struct btrfs_dio_private *dip = bio->bi_private; > + > + if (err) { > + printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " > + "disk_bytenr %lu len %u err no %d\n", > + dip->inode->i_ino, bio->bi_rw, bio->bi_sector, > + bio->bi_size, err); > + dip->errors = 1; > + > + /* > + * before atomic variable goto zero, we must make sure > + * dip->errors is perceived to be set. > + */ > + smp_mb__before_atomic_dec(); > + } > + > + /* if there are more bios still pending for this dio, just exit */ > + if (!atomic_dec_and_test(&dip->pending_bios)) > + goto out; > + > + if (dip->errors) > + bio_io_error(dip->orig_bio); > + else { > + set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); > + bio_endio(dip->orig_bio, 0); > + } > +out: > + bio_put(bio); > +} > + > +static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, > + u64 first_sector, gfp_t gfp_flags) > +{ > + int nr_vecs = bio_get_nr_vecs(bdev); > + return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags); > +} > + > +static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, > + int rw, u64 file_offset, int skip_sum, > + u32 *csums) > +{ > + int write = rw & REQ_WRITE; > + struct btrfs_root *root = BTRFS_I(inode)->root; > + int ret; > + > + bio_get(bio); > + ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); > + if (ret) > + goto err; > + > + if (write && !skip_sum) { > + ret = btrfs_wq_submit_bio(root->fs_info, > + inode, rw, bio, 0, 0, > + file_offset, > + __btrfs_submit_bio_start_direct_io, > + __btrfs_submit_bio_done); > + goto err; > + } else if (!skip_sum) > + btrfs_lookup_bio_sums_dio(root, inode, bio, > + file_offset, csums); > + > + ret = btrfs_map_bio(root, rw, bio, 0, 1); > +err: > + bio_put(bio); > + return ret; > +} > + > +static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, > + int skip_sum) > +{ > + struct inode *inode = dip->inode; > + struct btrfs_root *root = BTRFS_I(inode)->root; > + struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; > + struct bio *bio; > + struct bio *orig_bio = dip->orig_bio; > + struct bio_vec *bvec = orig_bio->bi_io_vec; > + u64 start_sector = orig_bio->bi_sector; > + u64 file_offset = dip->logical_offset; > + u64 submit_len = 0; > + u64 map_length; > + int nr_pages = 0; > + u32 *csums = dip->csums; > + int ret = 0; > + > + bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); > + if (!bio) > + return -ENOMEM; > + bio->bi_private = dip; > + bio->bi_end_io = btrfs_end_dio_bio; > + atomic_inc(&dip->pending_bios); > + > + map_length = orig_bio->bi_size; > + ret = btrfs_map_block(map_tree, READ, start_sector << 9, > + &map_length, NULL, 0); > + if (ret) { > + bio_put(bio); > + return -EIO; > + } > + > + while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { > + if (unlikely(map_length < submit_len + bvec->bv_len || > + bio_add_page(bio, bvec->bv_page, bvec->bv_len, > + bvec->bv_offset) < bvec->bv_len)) { > + /* > + * inc the count before we submit the bio so > + * we know the end IO handler won''t happen before > + * we inc the count. Otherwise, the dip might get freed > + * before we''re done setting it up > + */ > + atomic_inc(&dip->pending_bios); > + ret = __btrfs_submit_dio_bio(bio, inode, rw, > + file_offset, skip_sum, > + csums); > + if (ret) { > + bio_put(bio); > + atomic_dec(&dip->pending_bios); > + goto out_err; > + } > + > + if (!skip_sum) > + csums = csums + nr_pages; > + start_sector += submit_len >> 9; > + file_offset += submit_len; > + > + submit_len = 0; > + nr_pages = 0; > + > + bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, > + start_sector, GFP_NOFS); > + if (!bio) > + goto out_err; > + bio->bi_private = dip; > + bio->bi_end_io = btrfs_end_dio_bio; > + > + map_length = orig_bio->bi_size; > + ret = btrfs_map_block(map_tree, READ, start_sector << 9, > + &map_length, NULL, 0); > + if (ret) { > + bio_put(bio); > + goto out_err; > + } > + } else { > + submit_len += bvec->bv_len; > + nr_pages ++; > + bvec++; > + } > + } > + > + ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, > + csums); > + if (!ret) > + return 0; > + > + bio_put(bio); > +out_err: > + dip->errors = 1; > + /* > + * before atomic variable goto zero, we must > + * make sure dip->errors is perceived to be set. > + */ > + smp_mb__before_atomic_dec(); > + if (atomic_dec_and_test(&dip->pending_bios)) > + bio_io_error(dip->orig_bio); > + > + /* bio_end_io() will handle error, so we needn''t return it */ > + return 0; > +} > + > static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, > loff_t file_offset) > { > @@ -5723,33 +5901,18 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, > > dip->disk_bytenr = (u64)bio->bi_sector << 9; > bio->bi_private = dip; > + dip->errors = 0; > + dip->orig_bio = bio; > + atomic_set(&dip->pending_bios, 0); > > if (write) > bio->bi_end_io = btrfs_endio_direct_write; > else > bio->bi_end_io = btrfs_endio_direct_read; > > - ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); > - if (ret) > - goto free_ordered; > - > - if (write && !skip_sum) { > - ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, > - inode, rw, bio, 0, 0, > - dip->logical_offset, > - __btrfs_submit_bio_start_direct_io, > - __btrfs_submit_bio_done); > - if (ret) > - goto free_ordered; > + ret = btrfs_submit_direct_hook(rw, dip, skip_sum); > + if (!ret) > return; > - } else if (!skip_sum) > - btrfs_lookup_bio_sums_dio(root, inode, bio, > - dip->logical_offset, dip->csums); > - > - ret = btrfs_map_bio(root, rw, bio, 0, 1); > - if (ret) > - goto free_ordered; > - return; > free_ordered: > /* > * If this is a write, we need to clean up the reserved space and kill-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Chris Mason
2010-Nov-29 01:55 UTC
Re: [PATCH -V2 3/3] btrfs: fix panic caused by direct IO
Excerpts from Chris Mason''s message of 2010-11-21 22:18:54 -0500:> Great, I''ll test this and the others overnight. Thanks! > > -chris > > Excerpts from Miao Xie''s message of 2010-11-21 22:04:43 -0500: > > V1->V2 Changes: > > change the fix method. we split bios in btrfs_submit_direct() to fix this > > problem now. > > > > btrfs paniced when we write >64KB data by direct IO at one time. > > > > Reproduce steps: > > # mkfs.btrfs /dev/sda5 /dev/sda6 > > # mount /dev/sda5 /mnt > > # dd if=/dev/zero of=/mnt/tmpfile bs=100K count=1 oflag=directThanks again for coding this up, the implementation looks good to me. This easily passed the basic tests, but I ran into trouble when I tried using it to server my virtual machines. The problem is that we create ordered extents in the DIO get_blocks call, but the generic DIO code may create a single bio to span more than one ordered extent by merging adjacent ranges. I''ve fixed it here by walking forward through the ordered extents in the end_io processing. I''ve pushed these changes out to the next-rc branch of the btrfs unstable tree, and the last commit is here: Could you please take a look and verify it still works with your tests? http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-unstable.git;a=commit;h=163cf09c2a0ee5cac6285f9347975bd1e97725da -chris -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, 28 Nov 2010 20:55:28 -0500, Chris Mason wrote:> Excerpts from Chris Mason''s message of 2010-11-21 22:18:54 -0500: >> Great, I''ll test this and the others overnight. Thanks! >> >> -chris >> >> Excerpts from Miao Xie''s message of 2010-11-21 22:04:43 -0500: >>> V1->V2 Changes: >>> change the fix method. we split bios in btrfs_submit_direct() to fix this >>> problem now. >>> >>> btrfs paniced when we write>64KB data by direct IO at one time. >>> >>> Reproduce steps: >>> # mkfs.btrfs /dev/sda5 /dev/sda6 >>> # mount /dev/sda5 /mnt >>> # dd if=/dev/zero of=/mnt/tmpfile bs=100K count=1 oflag=direct > > Thanks again for coding this up, the implementation looks good to me. > > This easily passed the basic tests, but I ran into trouble when I tried > using it to server my virtual machines. The problem is that we create > ordered extents in the DIO get_blocks call, but the generic DIO code > may create a single bio to span more than one ordered extent by merging > adjacent ranges. I''ve fixed it here by walking forward through the > ordered extents in the end_io processing. > > I''ve pushed these changes out to the next-rc branch of the btrfs > unstable tree, and the last commit is here: > > Could you please take a look and verify it still works with your tests? > > http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-unstable.git;a=commit;h=163cf09c2a0ee5cac6285f9347975bd1e97725daOK, I will do it soon. Thanks Miao -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, Chris On Sun, 28 Nov 2010 20:55:28 -0500, Chris Mason wrote:> Excerpts from Chris Mason''s message of 2010-11-21 22:18:54 -0500: >> Great, I''ll test this and the others overnight. Thanks! >> >> -chris >> >> Excerpts from Miao Xie''s message of 2010-11-21 22:04:43 -0500: >>> V1->V2 Changes: >>> change the fix method. we split bios in btrfs_submit_direct() to fix this >>> problem now. >>> >>> btrfs paniced when we write>64KB data by direct IO at one time. >>> >>> Reproduce steps: >>> # mkfs.btrfs /dev/sda5 /dev/sda6 >>> # mount /dev/sda5 /mnt >>> # dd if=/dev/zero of=/mnt/tmpfile bs=100K count=1 oflag=direct > > Thanks again for coding this up, the implementation looks good to me. > > This easily passed the basic tests, but I ran into trouble when I tried > using it to server my virtual machines. The problem is that we create > ordered extents in the DIO get_blocks call, but the generic DIO code > may create a single bio to span more than one ordered extent by merging > adjacent ranges. I''ve fixed it here by walking forward through the > ordered extents in the end_io processing. > > I''ve pushed these changes out to the next-rc branch of the btrfs > unstable tree, and the last commit is here: > > Could you please take a look and verify it still works with your tests? > > http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-unstable.git;a=commit;h=163cf09c2a0ee5cac6285f9347975bd1e97725daI have tested it, and It works well. Thanks Miao> > -chris >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html