* [PATCH] Btrfs: create a pinned em when writing to a prealloc range in DIO
@ 2012-09-11 19:42 Josef Bacik
2012-09-11 22:16 ` Wade Cline
0 siblings, 1 reply; 2+ messages in thread
From: Josef Bacik @ 2012-09-11 19:42 UTC (permalink / raw)
To: linux-btrfs
Wade Cline reported a problem where he was getting garbage and warnings when
writing to a preallocated range via O_DIRECT. This is because we weren't
creating our normal pinned extent_map for the range we were writing to,
which was causing all sorts of issues. This patch fixes the problem and
makes his testcase much happier. Thanks,
Reported-by: Wade Cline <clinew@linux.vnet.ibm.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
---
fs/btrfs/inode.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e7107bd..ccc3310 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6513,6 +6513,48 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
return ret;
}
+static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
+ u64 len, u64 orig_start,
+ u64 block_start, u64 block_len,
+ int type)
+{
+ struct extent_map_tree *em_tree;
+ struct extent_map *em;
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ int ret;
+
+ em_tree = &BTRFS_I(inode)->extent_tree;
+ em = alloc_extent_map();
+ if (!em)
+ return ERR_PTR(-ENOMEM);
+
+ em->start = start;
+ em->orig_start = orig_start;
+ em->len = len;
+ em->block_len = block_len;
+ em->block_start = block_start;
+ em->bdev = root->fs_info->fs_devices->latest_bdev;
+ set_bit(EXTENT_FLAG_PINNED, &em->flags);
+ if (type == BTRFS_ORDERED_PREALLOC)
+ set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+
+ do {
+ btrfs_drop_extent_cache(inode, em->start,
+ em->start + em->len - 1, 0);
+ write_lock(&em_tree->lock);
+ ret = add_extent_mapping(em_tree, em);
+ write_unlock(&em_tree->lock);
+ } while (ret == -EEXIST);
+
+ if (ret) {
+ free_extent_map(em);
+ return ERR_PTR(ret);
+ }
+
+ return em;
+}
+
+
static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
@@ -6627,6 +6669,19 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
goto must_cow;
if (can_nocow_odirect(trans, inode, start, len) == 1) {
+ u64 orig_start = em->start;
+
+ if (type == BTRFS_ORDERED_PREALLOC) {
+ free_extent_map(em);
+ em = create_pinned_em(inode, start, len,
+ orig_start,
+ block_start, len, type);
+ if (IS_ERR(em)) {
+ btrfs_end_transaction(trans, root);
+ goto unlock_err;
+ }
+ }
+
ret = btrfs_add_ordered_extent_dio(inode, start,
block_start, len, len, type);
btrfs_end_transaction(trans, root);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Btrfs: create a pinned em when writing to a prealloc range in DIO
2012-09-11 19:42 [PATCH] Btrfs: create a pinned em when writing to a prealloc range in DIO Josef Bacik
@ 2012-09-11 22:16 ` Wade Cline
0 siblings, 0 replies; 2+ messages in thread
From: Wade Cline @ 2012-09-11 22:16 UTC (permalink / raw)
To: Josef Bacik; +Cc: linux-btrfs, mcao
On 09/11/2012 12:42 PM, Josef Bacik wrote:
> Wade Cline reported a problem where he was getting garbage and warnings when
> writing to a preallocated range via O_DIRECT. This is because we weren't
> creating our normal pinned extent_map for the range we were writing to,
> which was causing all sorts of issues. This patch fixes the problem and
> makes his testcase much happier. Thanks,
>
> Reported-by: Wade Cline<clinew@linux.vnet.ibm.com>
> Signed-off-by: Josef Bacik<jbacik@fusionio.com>
I ran some basic tests and this seems to have fixed the issue.
Tested-by: Wade Cline <clinew@linux.vnet.ibm.com>
Thank you,
Wade
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-09-11 22:16 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-11 19:42 [PATCH] Btrfs: create a pinned em when writing to a prealloc range in DIO Josef Bacik
2012-09-11 22:16 ` Wade Cline
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).