Message ID | 1386805122-23972-3-git-send-email-sekharan@us.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Dec 12, 2013 at 1:38 AM, Chandra Seetharaman <sekharan@us.ibm.com> wrote: > In order to handle a blocksize that is smaller than the > PAGE_SIZE, we need align all IOs to PAGE_SIZE. > > This patch defines a new macro btrfs_align_size() that > calculates the alignment size based on the sectorsize > and uses it at appropriate places. > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> > --- > fs/btrfs/btrfs_inode.h | 7 +++++++ > fs/btrfs/compression.c | 3 ++- > fs/btrfs/extent-tree.c | 12 ++++++------ > fs/btrfs/extent_io.c | 17 ++++++----------- > fs/btrfs/file.c | 15 +++++++-------- > fs/btrfs/inode.c | 41 ++++++++++++++++++++++------------------- > fs/btrfs/ioctl.c | 6 +++--- > fs/btrfs/ordered-data.c | 2 +- > fs/btrfs/tree-log.c | 2 +- > 9 files changed, 55 insertions(+), 50 deletions(-) > > diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h > index ac0b39d..eee994f 100644 > --- a/fs/btrfs/btrfs_inode.h > +++ b/fs/btrfs/btrfs_inode.h > @@ -280,4 +280,11 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) > &BTRFS_I(inode)->runtime_flags); > } > > +static inline u64 btrfs_align_size(struct inode *inode) > +{ > + if (BTRFS_I(inode)->root->sectorsize < PAGE_CACHE_SIZE) > + return (u64)PAGE_CACHE_SIZE; > + else > + return (u64)BTRFS_I(inode)->root->sectorsize; > +} for performance, isn't it worth to store this value instead of calculating it each time? > #endif > diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c > index 1499b27..259f2c5 100644 > --- a/fs/btrfs/compression.c > +++ b/fs/btrfs/compression.c > @@ -89,9 +89,10 @@ static inline int compressed_bio_size(struct btrfs_root *root, > unsigned long disk_size) > { > u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); > + int align_size = max_t(size_t, root->sectorsize, PAGE_CACHE_SIZE); > > return sizeof(struct compressed_bio) + > - ((disk_size + root->sectorsize - 1) / root->sectorsize) * > + ((disk_size + align_size - 1) / align_size) * > csum_size; > } > > diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c > index 79cf87f..621af18 100644 > --- a/fs/btrfs/extent-tree.c > +++ b/fs/btrfs/extent-tree.c > @@ -3617,8 +3617,8 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes) > u64 used; > int ret = 0, committed = 0, alloc_chunk = 1; > > - /* make sure bytes are sectorsize aligned */ > - bytes = ALIGN(bytes, root->sectorsize); > + /* make sure bytes are appropriately aligned */ > + bytes = ALIGN(bytes, btrfs_align_size(inode)); > > if (btrfs_is_free_space_inode(inode)) { > committed = 1; > @@ -3726,8 +3726,8 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes) > struct btrfs_root *root = BTRFS_I(inode)->root; > struct btrfs_space_info *data_sinfo; > > - /* make sure bytes are sectorsize aligned */ > - bytes = ALIGN(bytes, root->sectorsize); > + /* make sure bytes are appropriately aligned */ > + bytes = ALIGN(bytes, btrfs_align_size(inode)); > > data_sinfo = root->fs_info->data_sinfo; > spin_lock(&data_sinfo->lock); > @@ -4988,7 +4988,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) > if (delalloc_lock) > mutex_lock(&BTRFS_I(inode)->delalloc_mutex); > > - num_bytes = ALIGN(num_bytes, root->sectorsize); > + num_bytes = ALIGN(num_bytes, btrfs_align_size(inode)); > > spin_lock(&BTRFS_I(inode)->lock); > BTRFS_I(inode)->outstanding_extents++; > @@ -5126,7 +5126,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) > u64 to_free = 0; > unsigned dropped; > > - num_bytes = ALIGN(num_bytes, root->sectorsize); > + num_bytes = ALIGN(num_bytes, btrfs_align_size(inode)); > spin_lock(&BTRFS_I(inode)->lock); > dropped = drop_outstanding_extent(inode); > > diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c > index a1a849b..e1992ed 100644 > --- a/fs/btrfs/extent_io.c > +++ b/fs/btrfs/extent_io.c > @@ -2766,7 +2766,7 @@ static int __do_readpage(struct extent_io_tree *tree, > size_t pg_offset = 0; > size_t iosize; > size_t disk_io_size; > - size_t blocksize = inode->i_sb->s_blocksize; > + size_t blocksize = btrfs_align_size(inode); > unsigned long this_bio_flag = *bio_flags & EXTENT_BIO_PARENT_LOCKED; > > set_page_extent_mapped(page); > @@ -3078,7 +3078,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, > int ret; > int nr = 0; > size_t pg_offset = 0; > - size_t blocksize; > loff_t i_size = i_size_read(inode); > unsigned long end_index = i_size >> PAGE_CACHE_SHIFT; > u64 nr_delalloc; > @@ -3218,8 +3217,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, > goto done; > } > > - blocksize = inode->i_sb->s_blocksize; > - > while (cur <= end) { > if (cur >= last_byte) { > if (tree->ops && tree->ops->writepage_end_io_hook) > @@ -3238,7 +3235,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, > BUG_ON(extent_map_end(em) <= cur); > BUG_ON(end < cur); > iosize = min(extent_map_end(em) - cur, end - cur + 1); > - iosize = ALIGN(iosize, blocksize); > + iosize = ALIGN(iosize, btrfs_align_size(inode)); > sector = (em->block_start + extent_offset) >> 9; > bdev = em->bdev; > block_start = em->block_start; > @@ -3934,9 +3931,8 @@ int extent_invalidatepage(struct extent_io_tree *tree, > struct extent_state *cached_state = NULL; > u64 start = page_offset(page); > u64 end = start + PAGE_CACHE_SIZE - 1; > - size_t blocksize = page->mapping->host->i_sb->s_blocksize; > > - start += ALIGN(offset, blocksize); > + start += ALIGN(offset, btrfs_align_size(page->mapping->host)); > if (start > end) > return 0; > > @@ -4044,7 +4040,6 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, > u64 last, > get_extent_t *get_extent) > { > - u64 sectorsize = BTRFS_I(inode)->root->sectorsize; > struct extent_map *em; > u64 len; > > @@ -4055,7 +4050,7 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, > len = last - offset; > if (len == 0) > break; > - len = ALIGN(len, sectorsize); > + len = ALIGN(len, btrfs_align_size(inode)); > em = get_extent(inode, NULL, 0, offset, len, 0); > if (IS_ERR_OR_NULL(em)) > return em; > @@ -4119,8 +4114,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, > return -ENOMEM; > path->leave_spinning = 1; > > - start = ALIGN(start, BTRFS_I(inode)->root->sectorsize); > - len = ALIGN(len, BTRFS_I(inode)->root->sectorsize); > + start = ALIGN(start, btrfs_align_size(inode)); > + len = ALIGN(len, btrfs_align_size(inode)); > > /* > * lookup the last file extent. We're not using i_size here > diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c > index 82d0342..1861322 100644 > --- a/fs/btrfs/file.c > +++ b/fs/btrfs/file.c > @@ -505,8 +505,8 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, > u64 end_pos = pos + write_bytes; > loff_t isize = i_size_read(inode); > > - start_pos = pos & ~((u64)root->sectorsize - 1); > - num_bytes = ALIGN(write_bytes + pos - start_pos, root->sectorsize); > + start_pos = pos & ~(btrfs_align_size(inode) - 1); > + num_bytes = ALIGN(write_bytes + pos - start_pos, btrfs_align_size(inode)); > > end_of_last_block = start_pos + num_bytes - 1; > err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, > @@ -889,7 +889,7 @@ next_slot: > inode_sub_bytes(inode, > extent_end - key.offset); > extent_end = ALIGN(extent_end, > - root->sectorsize); > + btrfs_align_size(inode)); > } else if (update_refs && disk_bytenr > 0) { > ret = btrfs_free_extent(trans, root, > disk_bytenr, num_bytes, 0, > @@ -1254,7 +1254,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, > u64 start_pos; > u64 last_pos; > > - start_pos = pos & ~((u64)root->sectorsize - 1); > + start_pos = pos & ~((u64)btrfs_align_size(inode) - 1); > last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; > > again: > @@ -2263,11 +2263,10 @@ static long btrfs_fallocate(struct file *file, int mode, > u64 alloc_hint = 0; > u64 locked_end; > struct extent_map *em; > - int blocksize = BTRFS_I(inode)->root->sectorsize; > int ret; > > - alloc_start = round_down(offset, blocksize); > - alloc_end = round_up(offset + len, blocksize); > + alloc_start = round_down(offset, btrfs_align_size(inode)); > + alloc_end = round_up(offset + len, btrfs_align_size(inode)); > > /* Make sure we aren't being give some crap mode */ > if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) > @@ -2367,7 +2366,7 @@ static long btrfs_fallocate(struct file *file, int mode, > } > last_byte = min(extent_map_end(em), alloc_end); > actual_end = min_t(u64, extent_map_end(em), offset + len); > - last_byte = ALIGN(last_byte, blocksize); > + last_byte = ALIGN(last_byte, btrfs_align_size(inode)); > > if (em->block_start == EXTENT_MAP_HOLE || > (cur_offset >= inode->i_size && > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index f1a7744..c79c9cd 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -239,7 +239,7 @@ static noinline int cow_file_range_inline(struct btrfs_root *root, > u64 isize = i_size_read(inode); > u64 actual_end = min(end + 1, isize); > u64 inline_len = actual_end - start; > - u64 aligned_end = ALIGN(end, root->sectorsize); > + u64 aligned_end = ALIGN(end, btrfs_align_size(inode)); > u64 data_len = inline_len; > int ret; > > @@ -354,7 +354,6 @@ static noinline int compress_file_range(struct inode *inode, > { > struct btrfs_root *root = BTRFS_I(inode)->root; > u64 num_bytes; > - u64 blocksize = root->sectorsize; > u64 actual_end; > u64 isize = i_size_read(inode); > int ret = 0; > @@ -407,8 +406,8 @@ again: > * a compressed extent to 128k. > */ > total_compressed = min(total_compressed, max_uncompressed); > - num_bytes = ALIGN(end - start + 1, blocksize); > - num_bytes = max(blocksize, num_bytes); > + num_bytes = ALIGN(end - start + 1, btrfs_align_size(inode)); > + num_bytes = max(btrfs_align_size(inode), num_bytes); > total_in = 0; > ret = 0; > > @@ -508,7 +507,7 @@ cont: > * up to a block size boundary so the allocator does sane > * things > */ > - total_compressed = ALIGN(total_compressed, blocksize); > + total_compressed = ALIGN(total_compressed, btrfs_align_size(inode)); > > /* > * one last check to make sure the compression is really a > @@ -837,7 +836,6 @@ static noinline int cow_file_range(struct inode *inode, > unsigned long ram_size; > u64 disk_num_bytes; > u64 cur_alloc_size; > - u64 blocksize = root->sectorsize; > struct btrfs_key ins; > struct extent_map *em; > struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; > @@ -848,8 +846,8 @@ static noinline int cow_file_range(struct inode *inode, > return -EINVAL; > } > > - num_bytes = ALIGN(end - start + 1, blocksize); > - num_bytes = max(blocksize, num_bytes); > + num_bytes = ALIGN(end - start + 1, btrfs_align_size(inode)); > + num_bytes = max(btrfs_align_size(inode), num_bytes); > disk_num_bytes = num_bytes; > > /* if this is a small write inside eof, kick off defrag */ > @@ -1263,7 +1261,7 @@ next_slot: > } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { > extent_end = found_key.offset + > btrfs_file_extent_inline_len(leaf, fi); > - extent_end = ALIGN(extent_end, root->sectorsize); > + extent_end = ALIGN(extent_end, btrfs_align_size(inode)); > } else { > BUG_ON(1); > } > @@ -1389,6 +1387,12 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, > int ret; > struct btrfs_root *root = BTRFS_I(inode)->root; > > + if (inode->i_sb->s_blocksize < PAGE_CACHE_SIZE) { > + start &= ~(PAGE_CACHE_SIZE - 1); > + end = max_t(u64, start + PAGE_CACHE_SIZE - 1, end); > + } > + > + > if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) { > ret = run_delalloc_nocow(inode, locked_page, start, end, > page_started, 1, nr_written); > @@ -3894,7 +3898,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, > */ > if (root->ref_cows || root == root->fs_info->tree_root) > btrfs_drop_extent_cache(inode, ALIGN(new_size, > - root->sectorsize), (u64)-1, 0); > + btrfs_align_size(inode)), (u64)-1, 0); > > /* > * This function is also used to drop the items in the log tree before > @@ -3980,7 +3984,7 @@ search_again: > btrfs_file_extent_num_bytes(leaf, fi); > extent_num_bytes = ALIGN(new_size - > found_key.offset, > - root->sectorsize); > + btrfs_align_size(inode)); > btrfs_set_file_extent_num_bytes(leaf, fi, > extent_num_bytes); > num_dec = (orig_num_bytes - > @@ -4217,8 +4221,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) > struct extent_map *em = NULL; > struct extent_state *cached_state = NULL; > struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; > - u64 hole_start = ALIGN(oldsize, root->sectorsize); > - u64 block_end = ALIGN(size, root->sectorsize); > + u64 hole_start = ALIGN(oldsize, btrfs_align_size(inode)); > + u64 block_end = ALIGN(size, btrfs_align_size(inode)); > u64 last_byte; > u64 cur_offset; > u64 hole_size; > @@ -4261,7 +4265,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) > break; > } > last_byte = min(extent_map_end(em), block_end); > - last_byte = ALIGN(last_byte , root->sectorsize); > + last_byte = ALIGN(last_byte , btrfs_align_size(inode)); > if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { > struct extent_map *hole_em; > hole_size = last_byte - cur_offset; > @@ -6001,7 +6005,7 @@ again: > } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { > size_t size; > size = btrfs_file_extent_inline_len(leaf, item); > - extent_end = ALIGN(extent_start + size, root->sectorsize); > + extent_end = ALIGN(extent_start + size, btrfs_align_size(inode)); > } > next: > if (start >= extent_end) { > @@ -6074,7 +6078,7 @@ next: > copy_size = min_t(u64, PAGE_CACHE_SIZE - pg_offset, > size - extent_offset); > em->start = extent_start + extent_offset; > - em->len = ALIGN(copy_size, root->sectorsize); > + em->len = ALIGN(copy_size, btrfs_align_size(inode)); > em->orig_block_len = em->len; > em->orig_start = em->start; > if (compress_type) { > @@ -7967,7 +7971,6 @@ static int btrfs_getattr(struct vfsmount *mnt, > { > u64 delalloc_bytes; > struct inode *inode = dentry->d_inode; > - u32 blocksize = inode->i_sb->s_blocksize; > > generic_fillattr(inode, stat); > stat->dev = BTRFS_I(inode)->root->anon_dev; > @@ -7976,8 +7979,8 @@ static int btrfs_getattr(struct vfsmount *mnt, > spin_lock(&BTRFS_I(inode)->lock); > delalloc_bytes = BTRFS_I(inode)->delalloc_bytes; > spin_unlock(&BTRFS_I(inode)->lock); > - stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) + > - ALIGN(delalloc_bytes, blocksize)) >> 9; > + stat->blocks = (ALIGN(inode_get_bytes(inode), btrfs_align_size(inode)) + > + ALIGN(delalloc_bytes, btrfs_align_size(inode))) >> 9; > return 0; > } > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > index a111622..c41e342 100644 > --- a/fs/btrfs/ioctl.c > +++ b/fs/btrfs/ioctl.c > @@ -2631,7 +2631,7 @@ static int btrfs_cmp_data(struct inode *src, u64 loff, struct inode *dst, > > static int extent_same_check_offsets(struct inode *inode, u64 off, u64 len) > { > - u64 bs = BTRFS_I(inode)->root->fs_info->sb->s_blocksize; > + u64 bs = btrfs_align_size(inode); > > if (off + len > inode->i_size || off + len < off) > return -EINVAL; > @@ -2698,7 +2698,7 @@ static long btrfs_ioctl_file_extent_same(struct file *file, > int i; > int ret; > unsigned long size; > - u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize; > + u64 bs = btrfs_align_size(src); > bool is_admin = capable(CAP_SYS_ADMIN); > > if (!(file->f_mode & FMODE_READ)) > @@ -3111,7 +3111,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, > struct inode *src; > int ret; > u64 len = olen; > - u64 bs = root->fs_info->sb->s_blocksize; > + u64 bs = btrfs_align_size(inode); > int same_inode = 0; > > /* > diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c > index 69582d5..8d703e8 100644 > --- a/fs/btrfs/ordered-data.c > +++ b/fs/btrfs/ordered-data.c > @@ -936,7 +936,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, > ordered->file_offset + > ordered->truncated_len); > } else { > - offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); > + offset = ALIGN(offset, btrfs_align_size(inode)); > } > disk_i_size = BTRFS_I(inode)->disk_i_size; > > diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c > index 9f7fc51..455d288 100644 > --- a/fs/btrfs/tree-log.c > +++ b/fs/btrfs/tree-log.c > @@ -572,7 +572,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, > } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { > size = btrfs_file_extent_inline_len(eb, item); > nbytes = btrfs_file_extent_ram_bytes(eb, item); > - extent_end = ALIGN(start + size, root->sectorsize); > + extent_end = ALIGN(start + size, btrfs_align_size(inode)); > } else { > ret = 0; > goto out; > -- > 1.7.12.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Dec 16, 2013 at 02:33:11PM +0200, saeed bishara wrote: > On Thu, Dec 12, 2013 at 1:38 AM, Chandra Seetharaman > <sekharan@us.ibm.com> wrote: > > In order to handle a blocksize that is smaller than the > > PAGE_SIZE, we need align all IOs to PAGE_SIZE. > > > > This patch defines a new macro btrfs_align_size() that > > calculates the alignment size based on the sectorsize > > and uses it at appropriate places. > > > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> > > --- > > fs/btrfs/btrfs_inode.h | 7 +++++++ > > fs/btrfs/compression.c | 3 ++- > > fs/btrfs/extent-tree.c | 12 ++++++------ > > fs/btrfs/extent_io.c | 17 ++++++----------- > > fs/btrfs/file.c | 15 +++++++-------- > > fs/btrfs/inode.c | 41 ++++++++++++++++++++++------------------- > > fs/btrfs/ioctl.c | 6 +++--- > > fs/btrfs/ordered-data.c | 2 +- > > fs/btrfs/tree-log.c | 2 +- > > 9 files changed, 55 insertions(+), 50 deletions(-) > > > > diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h > > index ac0b39d..eee994f 100644 > > --- a/fs/btrfs/btrfs_inode.h > > +++ b/fs/btrfs/btrfs_inode.h > > @@ -280,4 +280,11 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) > > &BTRFS_I(inode)->runtime_flags); > > } > > > > +static inline u64 btrfs_align_size(struct inode *inode) > > +{ > > + if (BTRFS_I(inode)->root->sectorsize < PAGE_CACHE_SIZE) > > + return (u64)PAGE_CACHE_SIZE; > > + else > > + return (u64)BTRFS_I(inode)->root->sectorsize; > > +} > for performance, isn't it worth to store this value instead of > calculating it each time? I agree, would be better to add the corresponding item into fs_info, initialized as proposed above. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2013-12-16 at 15:48 +0100, David Sterba wrote: > On Mon, Dec 16, 2013 at 02:33:11PM +0200, saeed bishara wrote: > > On Thu, Dec 12, 2013 at 1:38 AM, Chandra Seetharaman > > <sekharan@us.ibm.com> wrote: > > > In order to handle a blocksize that is smaller than the > > > PAGE_SIZE, we need align all IOs to PAGE_SIZE. > > > > > > This patch defines a new macro btrfs_align_size() that > > > calculates the alignment size based on the sectorsize > > > and uses it at appropriate places. > > > > > > Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> > > > --- > > > fs/btrfs/btrfs_inode.h | 7 +++++++ > > > fs/btrfs/compression.c | 3 ++- > > > fs/btrfs/extent-tree.c | 12 ++++++------ > > > fs/btrfs/extent_io.c | 17 ++++++----------- > > > fs/btrfs/file.c | 15 +++++++-------- > > > fs/btrfs/inode.c | 41 ++++++++++++++++++++++------------------- > > > fs/btrfs/ioctl.c | 6 +++--- > > > fs/btrfs/ordered-data.c | 2 +- > > > fs/btrfs/tree-log.c | 2 +- > > > 9 files changed, 55 insertions(+), 50 deletions(-) > > > > > > diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h > > > index ac0b39d..eee994f 100644 > > > --- a/fs/btrfs/btrfs_inode.h > > > +++ b/fs/btrfs/btrfs_inode.h > > > @@ -280,4 +280,11 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) > > > &BTRFS_I(inode)->runtime_flags); > > > } > > > > > > +static inline u64 btrfs_align_size(struct inode *inode) > > > +{ > > > + if (BTRFS_I(inode)->root->sectorsize < PAGE_CACHE_SIZE) > > > + return (u64)PAGE_CACHE_SIZE; > > > + else > > > + return (u64)BTRFS_I(inode)->root->sectorsize; > > > +} > > for performance, isn't it worth to store this value instead of > > calculating it each time? Good suggestion Saeed. will do > > I agree, would be better to add the corresponding item into fs_info, > initialized as proposed above. Godd idea David. will do. > -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index ac0b39d..eee994f 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -280,4 +280,11 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) &BTRFS_I(inode)->runtime_flags); } +static inline u64 btrfs_align_size(struct inode *inode) +{ + if (BTRFS_I(inode)->root->sectorsize < PAGE_CACHE_SIZE) + return (u64)PAGE_CACHE_SIZE; + else + return (u64)BTRFS_I(inode)->root->sectorsize; +} #endif diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 1499b27..259f2c5 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -89,9 +89,10 @@ static inline int compressed_bio_size(struct btrfs_root *root, unsigned long disk_size) { u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); + int align_size = max_t(size_t, root->sectorsize, PAGE_CACHE_SIZE); return sizeof(struct compressed_bio) + - ((disk_size + root->sectorsize - 1) / root->sectorsize) * + ((disk_size + align_size - 1) / align_size) * csum_size; } diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 79cf87f..621af18 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3617,8 +3617,8 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes) u64 used; int ret = 0, committed = 0, alloc_chunk = 1; - /* make sure bytes are sectorsize aligned */ - bytes = ALIGN(bytes, root->sectorsize); + /* make sure bytes are appropriately aligned */ + bytes = ALIGN(bytes, btrfs_align_size(inode)); if (btrfs_is_free_space_inode(inode)) { committed = 1; @@ -3726,8 +3726,8 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes) struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_space_info *data_sinfo; - /* make sure bytes are sectorsize aligned */ - bytes = ALIGN(bytes, root->sectorsize); + /* make sure bytes are appropriately aligned */ + bytes = ALIGN(bytes, btrfs_align_size(inode)); data_sinfo = root->fs_info->data_sinfo; spin_lock(&data_sinfo->lock); @@ -4988,7 +4988,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) if (delalloc_lock) mutex_lock(&BTRFS_I(inode)->delalloc_mutex); - num_bytes = ALIGN(num_bytes, root->sectorsize); + num_bytes = ALIGN(num_bytes, btrfs_align_size(inode)); spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents++; @@ -5126,7 +5126,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) u64 to_free = 0; unsigned dropped; - num_bytes = ALIGN(num_bytes, root->sectorsize); + num_bytes = ALIGN(num_bytes, btrfs_align_size(inode)); spin_lock(&BTRFS_I(inode)->lock); dropped = drop_outstanding_extent(inode); diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index a1a849b..e1992ed 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2766,7 +2766,7 @@ static int __do_readpage(struct extent_io_tree *tree, size_t pg_offset = 0; size_t iosize; size_t disk_io_size; - size_t blocksize = inode->i_sb->s_blocksize; + size_t blocksize = btrfs_align_size(inode); unsigned long this_bio_flag = *bio_flags & EXTENT_BIO_PARENT_LOCKED; set_page_extent_mapped(page); @@ -3078,7 +3078,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, int ret; int nr = 0; size_t pg_offset = 0; - size_t blocksize; loff_t i_size = i_size_read(inode); unsigned long end_index = i_size >> PAGE_CACHE_SHIFT; u64 nr_delalloc; @@ -3218,8 +3217,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, goto done; } - blocksize = inode->i_sb->s_blocksize; - while (cur <= end) { if (cur >= last_byte) { if (tree->ops && tree->ops->writepage_end_io_hook) @@ -3238,7 +3235,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, BUG_ON(extent_map_end(em) <= cur); BUG_ON(end < cur); iosize = min(extent_map_end(em) - cur, end - cur + 1); - iosize = ALIGN(iosize, blocksize); + iosize = ALIGN(iosize, btrfs_align_size(inode)); sector = (em->block_start + extent_offset) >> 9; bdev = em->bdev; block_start = em->block_start; @@ -3934,9 +3931,8 @@ int extent_invalidatepage(struct extent_io_tree *tree, struct extent_state *cached_state = NULL; u64 start = page_offset(page); u64 end = start + PAGE_CACHE_SIZE - 1; - size_t blocksize = page->mapping->host->i_sb->s_blocksize; - start += ALIGN(offset, blocksize); + start += ALIGN(offset, btrfs_align_size(page->mapping->host)); if (start > end) return 0; @@ -4044,7 +4040,6 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, u64 last, get_extent_t *get_extent) { - u64 sectorsize = BTRFS_I(inode)->root->sectorsize; struct extent_map *em; u64 len; @@ -4055,7 +4050,7 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode, len = last - offset; if (len == 0) break; - len = ALIGN(len, sectorsize); + len = ALIGN(len, btrfs_align_size(inode)); em = get_extent(inode, NULL, 0, offset, len, 0); if (IS_ERR_OR_NULL(em)) return em; @@ -4119,8 +4114,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, return -ENOMEM; path->leave_spinning = 1; - start = ALIGN(start, BTRFS_I(inode)->root->sectorsize); - len = ALIGN(len, BTRFS_I(inode)->root->sectorsize); + start = ALIGN(start, btrfs_align_size(inode)); + len = ALIGN(len, btrfs_align_size(inode)); /* * lookup the last file extent. We're not using i_size here diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 82d0342..1861322 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -505,8 +505,8 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, u64 end_pos = pos + write_bytes; loff_t isize = i_size_read(inode); - start_pos = pos & ~((u64)root->sectorsize - 1); - num_bytes = ALIGN(write_bytes + pos - start_pos, root->sectorsize); + start_pos = pos & ~(btrfs_align_size(inode) - 1); + num_bytes = ALIGN(write_bytes + pos - start_pos, btrfs_align_size(inode)); end_of_last_block = start_pos + num_bytes - 1; err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, @@ -889,7 +889,7 @@ next_slot: inode_sub_bytes(inode, extent_end - key.offset); extent_end = ALIGN(extent_end, - root->sectorsize); + btrfs_align_size(inode)); } else if (update_refs && disk_bytenr > 0) { ret = btrfs_free_extent(trans, root, disk_bytenr, num_bytes, 0, @@ -1254,7 +1254,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, u64 start_pos; u64 last_pos; - start_pos = pos & ~((u64)root->sectorsize - 1); + start_pos = pos & ~((u64)btrfs_align_size(inode) - 1); last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; again: @@ -2263,11 +2263,10 @@ static long btrfs_fallocate(struct file *file, int mode, u64 alloc_hint = 0; u64 locked_end; struct extent_map *em; - int blocksize = BTRFS_I(inode)->root->sectorsize; int ret; - alloc_start = round_down(offset, blocksize); - alloc_end = round_up(offset + len, blocksize); + alloc_start = round_down(offset, btrfs_align_size(inode)); + alloc_end = round_up(offset + len, btrfs_align_size(inode)); /* Make sure we aren't being give some crap mode */ if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) @@ -2367,7 +2366,7 @@ static long btrfs_fallocate(struct file *file, int mode, } last_byte = min(extent_map_end(em), alloc_end); actual_end = min_t(u64, extent_map_end(em), offset + len); - last_byte = ALIGN(last_byte, blocksize); + last_byte = ALIGN(last_byte, btrfs_align_size(inode)); if (em->block_start == EXTENT_MAP_HOLE || (cur_offset >= inode->i_size && diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f1a7744..c79c9cd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -239,7 +239,7 @@ static noinline int cow_file_range_inline(struct btrfs_root *root, u64 isize = i_size_read(inode); u64 actual_end = min(end + 1, isize); u64 inline_len = actual_end - start; - u64 aligned_end = ALIGN(end, root->sectorsize); + u64 aligned_end = ALIGN(end, btrfs_align_size(inode)); u64 data_len = inline_len; int ret; @@ -354,7 +354,6 @@ static noinline int compress_file_range(struct inode *inode, { struct btrfs_root *root = BTRFS_I(inode)->root; u64 num_bytes; - u64 blocksize = root->sectorsize; u64 actual_end; u64 isize = i_size_read(inode); int ret = 0; @@ -407,8 +406,8 @@ again: * a compressed extent to 128k. */ total_compressed = min(total_compressed, max_uncompressed); - num_bytes = ALIGN(end - start + 1, blocksize); - num_bytes = max(blocksize, num_bytes); + num_bytes = ALIGN(end - start + 1, btrfs_align_size(inode)); + num_bytes = max(btrfs_align_size(inode), num_bytes); total_in = 0; ret = 0; @@ -508,7 +507,7 @@ cont: * up to a block size boundary so the allocator does sane * things */ - total_compressed = ALIGN(total_compressed, blocksize); + total_compressed = ALIGN(total_compressed, btrfs_align_size(inode)); /* * one last check to make sure the compression is really a @@ -837,7 +836,6 @@ static noinline int cow_file_range(struct inode *inode, unsigned long ram_size; u64 disk_num_bytes; u64 cur_alloc_size; - u64 blocksize = root->sectorsize; struct btrfs_key ins; struct extent_map *em; struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; @@ -848,8 +846,8 @@ static noinline int cow_file_range(struct inode *inode, return -EINVAL; } - num_bytes = ALIGN(end - start + 1, blocksize); - num_bytes = max(blocksize, num_bytes); + num_bytes = ALIGN(end - start + 1, btrfs_align_size(inode)); + num_bytes = max(btrfs_align_size(inode), num_bytes); disk_num_bytes = num_bytes; /* if this is a small write inside eof, kick off defrag */ @@ -1263,7 +1261,7 @@ next_slot: } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { extent_end = found_key.offset + btrfs_file_extent_inline_len(leaf, fi); - extent_end = ALIGN(extent_end, root->sectorsize); + extent_end = ALIGN(extent_end, btrfs_align_size(inode)); } else { BUG_ON(1); } @@ -1389,6 +1387,12 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, int ret; struct btrfs_root *root = BTRFS_I(inode)->root; + if (inode->i_sb->s_blocksize < PAGE_CACHE_SIZE) { + start &= ~(PAGE_CACHE_SIZE - 1); + end = max_t(u64, start + PAGE_CACHE_SIZE - 1, end); + } + + if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) { ret = run_delalloc_nocow(inode, locked_page, start, end, page_started, 1, nr_written); @@ -3894,7 +3898,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, */ if (root->ref_cows || root == root->fs_info->tree_root) btrfs_drop_extent_cache(inode, ALIGN(new_size, - root->sectorsize), (u64)-1, 0); + btrfs_align_size(inode)), (u64)-1, 0); /* * This function is also used to drop the items in the log tree before @@ -3980,7 +3984,7 @@ search_again: btrfs_file_extent_num_bytes(leaf, fi); extent_num_bytes = ALIGN(new_size - found_key.offset, - root->sectorsize); + btrfs_align_size(inode)); btrfs_set_file_extent_num_bytes(leaf, fi, extent_num_bytes); num_dec = (orig_num_bytes - @@ -4217,8 +4221,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) struct extent_map *em = NULL; struct extent_state *cached_state = NULL; struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; - u64 hole_start = ALIGN(oldsize, root->sectorsize); - u64 block_end = ALIGN(size, root->sectorsize); + u64 hole_start = ALIGN(oldsize, btrfs_align_size(inode)); + u64 block_end = ALIGN(size, btrfs_align_size(inode)); u64 last_byte; u64 cur_offset; u64 hole_size; @@ -4261,7 +4265,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) break; } last_byte = min(extent_map_end(em), block_end); - last_byte = ALIGN(last_byte , root->sectorsize); + last_byte = ALIGN(last_byte , btrfs_align_size(inode)); if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { struct extent_map *hole_em; hole_size = last_byte - cur_offset; @@ -6001,7 +6005,7 @@ again: } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { size_t size; size = btrfs_file_extent_inline_len(leaf, item); - extent_end = ALIGN(extent_start + size, root->sectorsize); + extent_end = ALIGN(extent_start + size, btrfs_align_size(inode)); } next: if (start >= extent_end) { @@ -6074,7 +6078,7 @@ next: copy_size = min_t(u64, PAGE_CACHE_SIZE - pg_offset, size - extent_offset); em->start = extent_start + extent_offset; - em->len = ALIGN(copy_size, root->sectorsize); + em->len = ALIGN(copy_size, btrfs_align_size(inode)); em->orig_block_len = em->len; em->orig_start = em->start; if (compress_type) { @@ -7967,7 +7971,6 @@ static int btrfs_getattr(struct vfsmount *mnt, { u64 delalloc_bytes; struct inode *inode = dentry->d_inode; - u32 blocksize = inode->i_sb->s_blocksize; generic_fillattr(inode, stat); stat->dev = BTRFS_I(inode)->root->anon_dev; @@ -7976,8 +7979,8 @@ static int btrfs_getattr(struct vfsmount *mnt, spin_lock(&BTRFS_I(inode)->lock); delalloc_bytes = BTRFS_I(inode)->delalloc_bytes; spin_unlock(&BTRFS_I(inode)->lock); - stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) + - ALIGN(delalloc_bytes, blocksize)) >> 9; + stat->blocks = (ALIGN(inode_get_bytes(inode), btrfs_align_size(inode)) + + ALIGN(delalloc_bytes, btrfs_align_size(inode))) >> 9; return 0; } diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a111622..c41e342 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -2631,7 +2631,7 @@ static int btrfs_cmp_data(struct inode *src, u64 loff, struct inode *dst, static int extent_same_check_offsets(struct inode *inode, u64 off, u64 len) { - u64 bs = BTRFS_I(inode)->root->fs_info->sb->s_blocksize; + u64 bs = btrfs_align_size(inode); if (off + len > inode->i_size || off + len < off) return -EINVAL; @@ -2698,7 +2698,7 @@ static long btrfs_ioctl_file_extent_same(struct file *file, int i; int ret; unsigned long size; - u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize; + u64 bs = btrfs_align_size(src); bool is_admin = capable(CAP_SYS_ADMIN); if (!(file->f_mode & FMODE_READ)) @@ -3111,7 +3111,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, struct inode *src; int ret; u64 len = olen; - u64 bs = root->fs_info->sb->s_blocksize; + u64 bs = btrfs_align_size(inode); int same_inode = 0; /* diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 69582d5..8d703e8 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -936,7 +936,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, ordered->file_offset + ordered->truncated_len); } else { - offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); + offset = ALIGN(offset, btrfs_align_size(inode)); } disk_i_size = BTRFS_I(inode)->disk_i_size; diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 9f7fc51..455d288 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -572,7 +572,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { size = btrfs_file_extent_inline_len(eb, item); nbytes = btrfs_file_extent_ram_bytes(eb, item); - extent_end = ALIGN(start + size, root->sectorsize); + extent_end = ALIGN(start + size, btrfs_align_size(inode)); } else { ret = 0; goto out;
In order to handle a blocksize that is smaller than the PAGE_SIZE, we need align all IOs to PAGE_SIZE. This patch defines a new macro btrfs_align_size() that calculates the alignment size based on the sectorsize and uses it at appropriate places. Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> --- fs/btrfs/btrfs_inode.h | 7 +++++++ fs/btrfs/compression.c | 3 ++- fs/btrfs/extent-tree.c | 12 ++++++------ fs/btrfs/extent_io.c | 17 ++++++----------- fs/btrfs/file.c | 15 +++++++-------- fs/btrfs/inode.c | 41 ++++++++++++++++++++++------------------- fs/btrfs/ioctl.c | 6 +++--- fs/btrfs/ordered-data.c | 2 +- fs/btrfs/tree-log.c | 2 +- 9 files changed, 55 insertions(+), 50 deletions(-)