aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2013-01-29 18:40:14 -0500
committerChris Mason <chris.mason@fusionio.com>2013-02-01 14:24:23 -0500
commit53b381b3abeb86f12787a6c40fee9b2f71edc23b (patch)
treec1018ba2157778f0200d2ede0c0df48fe5df8f14 /fs/btrfs/inode.c
parent64a167011bcabc1e855658387c8a4464b71f3138 (diff)
Btrfs: RAID5 and RAID6
This builds on David Woodhouse's original Btrfs raid5/6 implementation. The code has changed quite a bit, blame Chris Mason for any bugs. Read/modify/write is done after the higher levels of the filesystem have prepared a given bio. This means the higher layers are not responsible for building full stripes, and they don't need to query for the topology of the extents that may get allocated during delayed allocation runs. It also means different files can easily share the same stripe. But, it does expose us to incorrect parity if we crash or lose power while doing a read/modify/write cycle. This will be addressed in a later commit. Scrub is unable to repair crc errors on raid5/6 chunks. Discard does not work on raid5/6 (yet) The stripe size is fixed at 64KiB per disk. This will be tunable in a later commit. Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1b98c4ce3c6f..6f4e41dca970 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -39,6 +39,7 @@
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/ratelimit.h> 40#include <linux/ratelimit.h>
41#include <linux/mount.h> 41#include <linux/mount.h>
42#include <linux/blkdev.h>
42#include "compat.h" 43#include "compat.h"
43#include "ctree.h" 44#include "ctree.h"
44#include "disk-io.h" 45#include "disk-io.h"
@@ -6386,19 +6387,24 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
6386 int async_submit = 0; 6387 int async_submit = 0;
6387 6388
6388 map_length = orig_bio->bi_size; 6389 map_length = orig_bio->bi_size;
6389 ret = btrfs_map_block(root->fs_info, READ, start_sector << 9, 6390 ret = btrfs_map_block(root->fs_info, rw, start_sector << 9,
6390 &map_length, NULL, 0); 6391 &map_length, NULL, 0);
6391 if (ret) { 6392 if (ret) {
6392 bio_put(orig_bio); 6393 bio_put(orig_bio);
6393 return -EIO; 6394 return -EIO;
6394 } 6395 }
6395
6396 if (map_length >= orig_bio->bi_size) { 6396 if (map_length >= orig_bio->bi_size) {
6397 bio = orig_bio; 6397 bio = orig_bio;
6398 goto submit; 6398 goto submit;
6399 } 6399 }
6400 6400
6401 async_submit = 1; 6401 /* async crcs make it difficult to collect full stripe writes. */
6402 if (btrfs_get_alloc_profile(root, 1) &
6403 (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6))
6404 async_submit = 0;
6405 else
6406 async_submit = 1;
6407
6402 bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); 6408 bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS);
6403 if (!bio) 6409 if (!bio)
6404 return -ENOMEM; 6410 return -ENOMEM;
@@ -6440,7 +6446,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
6440 bio->bi_end_io = btrfs_end_dio_bio; 6446 bio->bi_end_io = btrfs_end_dio_bio;
6441 6447
6442 map_length = orig_bio->bi_size; 6448 map_length = orig_bio->bi_size;
6443 ret = btrfs_map_block(root->fs_info, READ, 6449 ret = btrfs_map_block(root->fs_info, rw,
6444 start_sector << 9, 6450 start_sector << 9,
6445 &map_length, NULL, 0); 6451 &map_length, NULL, 0);
6446 if (ret) { 6452 if (ret) {
@@ -6583,15 +6589,17 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
6583{ 6589{
6584 struct file *file = iocb->ki_filp; 6590 struct file *file = iocb->ki_filp;
6585 struct inode *inode = file->f_mapping->host; 6591 struct inode *inode = file->f_mapping->host;
6592 ssize_t ret;
6586 6593
6587 if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, 6594 if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov,
6588 offset, nr_segs)) 6595 offset, nr_segs))
6589 return 0; 6596 return 0;
6590 6597
6591 return __blockdev_direct_IO(rw, iocb, inode, 6598 ret = __blockdev_direct_IO(rw, iocb, inode,
6592 BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, 6599 BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev,
6593 iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, 6600 iov, offset, nr_segs, btrfs_get_blocks_direct, NULL,
6594 btrfs_submit_direct, 0); 6601 btrfs_submit_direct, 0);
6602 return ret;
6595} 6603}
6596 6604
6597#define BTRFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC) 6605#define BTRFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC)