#include <linux/statfs.h>
#include <linux/compat.h>
#include <linux/bit_spinlock.h>
-#include <linux/version.h>
#include <linux/xattr.h>
#include <linux/posix_acl.h>
#include <linux/falloc.h>
key.objectid = inode->i_ino;
key.offset = start;
btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY);
- inode_add_bytes(inode, size);
datasize = btrfs_file_extent_calc_inline_size(cur_size);
inode_add_bytes(inode, size);
struct btrfs_ordered_sum *sums;
LIST_HEAD(list);
- ret = btrfs_lookup_csums_range(root, bytenr, bytenr + num_bytes - 1,
- &list);
+ ret = btrfs_lookup_csums_range(root->fs_info->csum_root, bytenr,
+ bytenr + num_bytes - 1, &list);
if (ret == 0 && list_empty(&list))
return 0;
struct inode *inode, u64 file_offset,
struct list_head *list)
{
- struct list_head *cur;
struct btrfs_ordered_sum *sum;
btrfs_set_trans_block_group(trans, inode);
- list_for_each(cur, list) {
- sum = list_entry(cur, struct btrfs_ordered_sum, list);
+
+ list_for_each_entry(sum, list, list) {
btrfs_csum_file_blocks(trans,
BTRFS_I(inode)->root->fs_info->csum_root, sum);
}
int ret;
struct btrfs_root *root = BTRFS_I(inode)->root;
u32 csum = ~(u32)0;
- unsigned long flags;
if (PageChecked(page)) {
ClearPageChecked(page);
} else {
ret = get_state_private(io_tree, start, &private);
}
- local_irq_save(flags);
- kaddr = kmap_atomic(page, KM_IRQ0);
+ kaddr = kmap_atomic(page, KM_USER0);
if (ret)
goto zeroit;
if (csum != private)
goto zeroit;
- kunmap_atomic(kaddr, KM_IRQ0);
- local_irq_restore(flags);
+ kunmap_atomic(kaddr, KM_USER0);
good:
/* if the io failure tree for this inode is non-empty,
* check to see if we've recovered from a failed IO
(unsigned long long)private);
memset(kaddr + offset, 1, end - start + 1);
flush_dcache_page(page);
- kunmap_atomic(kaddr, KM_IRQ0);
- local_irq_restore(flags);
+ kunmap_atomic(kaddr, KM_USER0);
if (private == 0)
return 0;
return -EIO;
/* Reached end of directory/root. Bump pos past the last item. */
if (key_type == BTRFS_DIR_INDEX_KEY)
- filp->f_pos = INT_LIMIT(typeof(filp->f_pos));
+ filp->f_pos = INT_LIMIT(off_t);
else
filp->f_pos++;
nopos:
return -EINVAL;
}
-static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock)
+static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ __u64 start, __u64 len)
{
- return extent_bmap(mapping, iblock, btrfs_get_extent);
+ return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent);
}
int btrfs_readpage(struct file *file, struct page *page)
.clear_bit_hook = btrfs_clear_bit_hook,
};
+/*
+ * btrfs doesn't support the bmap operation because swapfiles
+ * use bmap to make a mapping of extents in the file. They assume
+ * these extents won't change over the life of the file and they
+ * use the bmap result to do IO directly to the drive.
+ *
+ * the btrfs bmap call would return logical addresses that aren't
+ * suitable for IO and they also will change frequently as COW
+ * operations happen. So, swapfile + btrfs == corruption.
+ *
+ * For now we're avoiding this by dropping bmap.
+ */
static struct address_space_operations btrfs_aops = {
.readpage = btrfs_readpage,
.writepage = btrfs_writepage,
.writepages = btrfs_writepages,
.readpages = btrfs_readpages,
.sync_page = block_sync_page,
- .bmap = btrfs_bmap,
.direct_IO = btrfs_direct_IO,
.invalidatepage = btrfs_invalidatepage,
.releasepage = btrfs_releasepage,
.removexattr = btrfs_removexattr,
.permission = btrfs_permission,
.fallocate = btrfs_fallocate,
+ .fiemap = btrfs_fiemap,
};
static struct inode_operations btrfs_special_inode_operations = {
.getattr = btrfs_getattr,