Loading fs/btrfs/ctree.c +24 −27 Original line number Diff line number Diff line Loading @@ -464,22 +464,12 @@ static int check_block(struct btrfs_root *root, struct btrfs_path *path, int level) { struct extent_buffer *buf = path->nodes[level]; char fsid[BTRFS_FSID_SIZE]; read_extent_buffer(buf, fsid, (unsigned long)btrfs_header_fsid(buf), BTRFS_FSID_SIZE); if (memcmp(fsid, root->fs_info->fsid, BTRFS_FSID_SIZE)) { int i = 0; if (memcmp_extent_buffer(buf, root->fs_info->fsid, (unsigned long)btrfs_header_fsid(buf), BTRFS_FSID_SIZE)) { printk("warning bad block %Lu\n", buf->start); if (!btrfs_buffer_uptodate(buf)) { WARN_ON(1); } for (i = 0; i < BTRFS_FSID_SIZE; i++) { printk("%x:%x ", root->fs_info->fsid[i], fsid[i]); } printk("\n"); // BUG(); BUG(); } if (level == 0) return check_leaf(root, path, level); Loading @@ -504,13 +494,14 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, int high = max; int mid; int ret; struct btrfs_disk_key *tmp; struct btrfs_disk_key *tmp = NULL; struct btrfs_disk_key unaligned; unsigned long offset; char *map_token = NULL; char *kaddr = NULL; unsigned long map_start = 0; unsigned long map_len = 0; int err; while(low < high) { mid = (low + high) / 2; Loading @@ -519,19 +510,24 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, if (!map_token || offset < map_start || (offset + sizeof(struct btrfs_disk_key)) > map_start + map_len) { if (map_token) if (map_token) { unmap_extent_buffer(eb, map_token, KM_USER0); map_extent_buffer(eb, offset, &map_token, &kaddr, map_token = NULL; } err = map_extent_buffer(eb, offset, sizeof(struct btrfs_disk_key), &map_token, &kaddr, &map_start, &map_len, KM_USER0); } if (offset + sizeof(struct btrfs_disk_key) > map_start + map_len) { unmap_extent_buffer(eb, map_token, KM_USER0); if (!err) { tmp = (struct btrfs_disk_key *)(kaddr + offset - map_start); } else { read_extent_buffer(eb, &unaligned, offset, sizeof(unaligned)); map_token = NULL; tmp = &unaligned; } } else { tmp = (struct btrfs_disk_key *)(kaddr + offset - map_start); Loading @@ -544,6 +540,7 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, high = mid; else { *slot = mid; if (map_token) unmap_extent_buffer(eb, map_token, KM_USER0); return 0; } Loading fs/btrfs/ctree.h +43 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/fs.h> #include <linux/workqueue.h> #include <linux/completion.h> #include <asm/kmap_types.h> #include "bit-radix.h" #include "extent_map.h" Loading Loading @@ -431,15 +432,52 @@ struct btrfs_root { static inline u##bits btrfs_##name(struct extent_buffer *eb, \ type *s) \ { \ int err; \ char *map_token; \ char *kaddr; \ unsigned long map_start; \ unsigned long map_len; \ unsigned long offset = (unsigned long)s + \ offsetof(type, member); \ err = map_extent_buffer(eb, offset, \ sizeof(((type *)0)->member), \ &map_token, &kaddr, \ &map_start, &map_len, KM_USER0); \ if (!err) { \ __le##bits *tmp = (__le##bits *)(kaddr + offset - \ map_start); \ u##bits res = le##bits##_to_cpu(*tmp); \ unmap_extent_buffer(eb, map_token, KM_USER0); \ return res; \ } else { \ __le##bits res; \ read_eb_member(eb, s, type, member, &res); \ return le##bits##_to_cpu(res); \ } \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ type *s, u##bits val) \ { \ int err; \ char *map_token; \ char *kaddr; \ unsigned long map_start; \ unsigned long map_len; \ unsigned long offset = (unsigned long)s + \ offsetof(type, member); \ err = map_extent_buffer(eb, offset, \ sizeof(((type *)0)->member), \ &map_token, &kaddr, \ &map_start, &map_len, KM_USER0); \ if (!err) { \ __le##bits *tmp = (__le##bits *)(kaddr + offset - \ map_start); \ *tmp = cpu_to_le##bits(val); \ unmap_extent_buffer(eb, map_token, KM_USER0); \ } else { \ val = cpu_to_le##bits(val); \ write_eb_member(eb, s, type, member, &val); \ } \ } #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ Loading fs/btrfs/extent_map.c +8 −3 Original line number Diff line number Diff line Loading @@ -2140,14 +2140,20 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, EXPORT_SYMBOL(read_extent_buffer); int map_extent_buffer(struct extent_buffer *eb, unsigned long start, unsigned long min_len, char **token, char **map, unsigned long *map_start, unsigned long *map_len, int km) { size_t offset; size_t offset = start & (PAGE_CACHE_SIZE - 1); char *kaddr; size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; unsigned long end_i = (start_offset + start + min_len) >> PAGE_CACHE_SHIFT; if (i != end_i) return -EINVAL; WARN_ON(start > eb->len); Loading @@ -2155,8 +2161,7 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start, offset = start_offset; *map_start = 0; } else { offset = 0; *map_start = (i << PAGE_CACHE_SHIFT) - offset; *map_start = (i << PAGE_CACHE_SHIFT) - start_offset; } // kaddr = kmap_atomic(eb->pages[i], km); Loading fs/btrfs/extent_map.h +1 −1 Original line number Diff line number Diff line Loading @@ -173,7 +173,7 @@ int set_extent_buffer_uptodate(struct extent_map_tree *tree, int extent_buffer_uptodate(struct extent_map_tree *tree, struct extent_buffer *eb); int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, char **token, char **map, unsigned long min_len, char **token, char **map, unsigned long *map_start, unsigned long *map_len, int km); void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km); Loading Loading
fs/btrfs/ctree.c +24 −27 Original line number Diff line number Diff line Loading @@ -464,22 +464,12 @@ static int check_block(struct btrfs_root *root, struct btrfs_path *path, int level) { struct extent_buffer *buf = path->nodes[level]; char fsid[BTRFS_FSID_SIZE]; read_extent_buffer(buf, fsid, (unsigned long)btrfs_header_fsid(buf), BTRFS_FSID_SIZE); if (memcmp(fsid, root->fs_info->fsid, BTRFS_FSID_SIZE)) { int i = 0; if (memcmp_extent_buffer(buf, root->fs_info->fsid, (unsigned long)btrfs_header_fsid(buf), BTRFS_FSID_SIZE)) { printk("warning bad block %Lu\n", buf->start); if (!btrfs_buffer_uptodate(buf)) { WARN_ON(1); } for (i = 0; i < BTRFS_FSID_SIZE; i++) { printk("%x:%x ", root->fs_info->fsid[i], fsid[i]); } printk("\n"); // BUG(); BUG(); } if (level == 0) return check_leaf(root, path, level); Loading @@ -504,13 +494,14 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, int high = max; int mid; int ret; struct btrfs_disk_key *tmp; struct btrfs_disk_key *tmp = NULL; struct btrfs_disk_key unaligned; unsigned long offset; char *map_token = NULL; char *kaddr = NULL; unsigned long map_start = 0; unsigned long map_len = 0; int err; while(low < high) { mid = (low + high) / 2; Loading @@ -519,19 +510,24 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, if (!map_token || offset < map_start || (offset + sizeof(struct btrfs_disk_key)) > map_start + map_len) { if (map_token) if (map_token) { unmap_extent_buffer(eb, map_token, KM_USER0); map_extent_buffer(eb, offset, &map_token, &kaddr, map_token = NULL; } err = map_extent_buffer(eb, offset, sizeof(struct btrfs_disk_key), &map_token, &kaddr, &map_start, &map_len, KM_USER0); } if (offset + sizeof(struct btrfs_disk_key) > map_start + map_len) { unmap_extent_buffer(eb, map_token, KM_USER0); if (!err) { tmp = (struct btrfs_disk_key *)(kaddr + offset - map_start); } else { read_extent_buffer(eb, &unaligned, offset, sizeof(unaligned)); map_token = NULL; tmp = &unaligned; } } else { tmp = (struct btrfs_disk_key *)(kaddr + offset - map_start); Loading @@ -544,6 +540,7 @@ static int generic_bin_search(struct extent_buffer *eb, unsigned long p, high = mid; else { *slot = mid; if (map_token) unmap_extent_buffer(eb, map_token, KM_USER0); return 0; } Loading
fs/btrfs/ctree.h +43 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/fs.h> #include <linux/workqueue.h> #include <linux/completion.h> #include <asm/kmap_types.h> #include "bit-radix.h" #include "extent_map.h" Loading Loading @@ -431,15 +432,52 @@ struct btrfs_root { static inline u##bits btrfs_##name(struct extent_buffer *eb, \ type *s) \ { \ int err; \ char *map_token; \ char *kaddr; \ unsigned long map_start; \ unsigned long map_len; \ unsigned long offset = (unsigned long)s + \ offsetof(type, member); \ err = map_extent_buffer(eb, offset, \ sizeof(((type *)0)->member), \ &map_token, &kaddr, \ &map_start, &map_len, KM_USER0); \ if (!err) { \ __le##bits *tmp = (__le##bits *)(kaddr + offset - \ map_start); \ u##bits res = le##bits##_to_cpu(*tmp); \ unmap_extent_buffer(eb, map_token, KM_USER0); \ return res; \ } else { \ __le##bits res; \ read_eb_member(eb, s, type, member, &res); \ return le##bits##_to_cpu(res); \ } \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ type *s, u##bits val) \ { \ int err; \ char *map_token; \ char *kaddr; \ unsigned long map_start; \ unsigned long map_len; \ unsigned long offset = (unsigned long)s + \ offsetof(type, member); \ err = map_extent_buffer(eb, offset, \ sizeof(((type *)0)->member), \ &map_token, &kaddr, \ &map_start, &map_len, KM_USER0); \ if (!err) { \ __le##bits *tmp = (__le##bits *)(kaddr + offset - \ map_start); \ *tmp = cpu_to_le##bits(val); \ unmap_extent_buffer(eb, map_token, KM_USER0); \ } else { \ val = cpu_to_le##bits(val); \ write_eb_member(eb, s, type, member, &val); \ } \ } #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ Loading
fs/btrfs/extent_map.c +8 −3 Original line number Diff line number Diff line Loading @@ -2140,14 +2140,20 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, EXPORT_SYMBOL(read_extent_buffer); int map_extent_buffer(struct extent_buffer *eb, unsigned long start, unsigned long min_len, char **token, char **map, unsigned long *map_start, unsigned long *map_len, int km) { size_t offset; size_t offset = start & (PAGE_CACHE_SIZE - 1); char *kaddr; size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; unsigned long end_i = (start_offset + start + min_len) >> PAGE_CACHE_SHIFT; if (i != end_i) return -EINVAL; WARN_ON(start > eb->len); Loading @@ -2155,8 +2161,7 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start, offset = start_offset; *map_start = 0; } else { offset = 0; *map_start = (i << PAGE_CACHE_SHIFT) - offset; *map_start = (i << PAGE_CACHE_SHIFT) - start_offset; } // kaddr = kmap_atomic(eb->pages[i], km); Loading
fs/btrfs/extent_map.h +1 −1 Original line number Diff line number Diff line Loading @@ -173,7 +173,7 @@ int set_extent_buffer_uptodate(struct extent_map_tree *tree, int extent_buffer_uptodate(struct extent_map_tree *tree, struct extent_buffer *eb); int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, char **token, char **map, unsigned long min_len, char **token, char **map, unsigned long *map_start, unsigned long *map_len, int km); void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km); Loading