Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128708
b: refs/heads/master
c: 1643298
h: refs/heads/master
v: v3
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent 0584cea commit cded6bb
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 85d824c4a407ba8dbd897f4e05bbe21bf24cc071
refs/heads/master: 16432985920f3c45af82da214e2498f3e2f9066b
11 changes: 9 additions & 2 deletions trunk/fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
PAGE_CACHE_SIZE / (sizeof(struct page *)));
pinned[0] = NULL;
pinned[1] = NULL;
if (file->f_flags & O_DIRECT)
return -EINVAL;

pos = *ppos;
start_pos = pos;
Expand Down Expand Up @@ -909,6 +907,15 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
start_pos, num_written);
if (err < 0)
num_written = err;
} else if (num_written > 0 && (file->f_flags & O_DIRECT)) {
do_sync_mapping_range(inode->i_mapping, start_pos,
start_pos + num_written - 1,
SYNC_FILE_RANGE_WRITE |
SYNC_FILE_RANGE_WAIT_AFTER);

invalidate_mapping_pages(inode->i_mapping,
start_pos >> PAGE_CACHE_SHIFT,
(start_pos + num_written - 1) >> PAGE_CACHE_SHIFT);
}
current->backing_dev_info = NULL;
return num_written ? num_written : err;
Expand Down
66 changes: 66 additions & 0 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2265,6 +2265,70 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
return em;
}

static int btrfs_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
struct extent_map *em;
u64 start = (u64)iblock << inode->i_blkbits;
struct btrfs_multi_bio *multi = NULL;
struct btrfs_root *root = BTRFS_I(inode)->root;
u64 len;
u64 logical;
u64 map_length;
int ret = 0;

em = btrfs_get_extent(inode, NULL, 0, start, bh_result->b_size, 0);

if (!em || IS_ERR(em))
goto out;

if (em->start > start || em->start + em->len <= start)
goto out;

if (em->block_start == EXTENT_MAP_INLINE) {
ret = -EINVAL;
goto out;
}

if (em->block_start == EXTENT_MAP_HOLE ||
em->block_start == EXTENT_MAP_DELALLOC) {
goto out;
}

len = em->start + em->len - start;
len = min_t(u64, len, INT_LIMIT(typeof(bh_result->b_size)));

logical = start - em->start;
logical = em->block_start + logical;

map_length = len;
ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
logical, &map_length, &multi, 0);
BUG_ON(ret);
bh_result->b_blocknr = multi->stripes[0].physical >> inode->i_blkbits;
bh_result->b_size = min(map_length, len);
bh_result->b_bdev = multi->stripes[0].dev->bdev;
set_buffer_mapped(bh_result);
kfree(multi);
out:
free_extent_map(em);
return ret;
}

static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
const struct iovec *iov, loff_t offset,
unsigned long nr_segs)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;

if (rw == WRITE)
return -EINVAL;

return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, btrfs_get_block, NULL);
}

static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock)
{
return extent_bmap(mapping, iblock, btrfs_get_extent);
Expand Down Expand Up @@ -3136,6 +3200,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
btrfs_throttle(root);
return err;
}

static int btrfs_permission(struct inode *inode, int mask,
struct nameidata *nd)
{
Expand Down Expand Up @@ -3193,6 +3258,7 @@ static struct address_space_operations btrfs_aops = {
.readpages = btrfs_readpages,
.sync_page = block_sync_page,
.bmap = btrfs_bmap,
.direct_IO = btrfs_direct_IO,
.invalidatepage = btrfs_invalidatepage,
.releasepage = btrfs_releasepage,
.set_page_dirty = __set_page_dirty_nobuffers,
Expand Down

0 comments on commit cded6bb

Please sign in to comment.