diff options
Diffstat (limited to 'fs/ocfs2/refcounttree.c')
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 58 |
1 files changed, 13 insertions, 45 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 998b17eda09d..a70d604593b6 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | 49 | ||
| 50 | struct ocfs2_cow_context { | 50 | struct ocfs2_cow_context { |
| 51 | struct inode *inode; | 51 | struct inode *inode; |
| 52 | struct file *file; | ||
| 53 | u32 cow_start; | 52 | u32 cow_start; |
| 54 | u32 cow_len; | 53 | u32 cow_len; |
| 55 | struct ocfs2_extent_tree data_et; | 54 | struct ocfs2_extent_tree data_et; |
| @@ -66,7 +65,7 @@ struct ocfs2_cow_context { | |||
| 66 | u32 *num_clusters, | 65 | u32 *num_clusters, |
| 67 | unsigned int *extent_flags); | 66 | unsigned int *extent_flags); |
| 68 | int (*cow_duplicate_clusters)(handle_t *handle, | 67 | int (*cow_duplicate_clusters)(handle_t *handle, |
| 69 | struct file *file, | 68 | struct inode *inode, |
| 70 | u32 cpos, u32 old_cluster, | 69 | u32 cpos, u32 old_cluster, |
| 71 | u32 new_cluster, u32 new_len); | 70 | u32 new_cluster, u32 new_len); |
| 72 | }; | 71 | }; |
| @@ -2922,14 +2921,12 @@ static int ocfs2_clear_cow_buffer(handle_t *handle, struct buffer_head *bh) | |||
| 2922 | } | 2921 | } |
| 2923 | 2922 | ||
| 2924 | int ocfs2_duplicate_clusters_by_page(handle_t *handle, | 2923 | int ocfs2_duplicate_clusters_by_page(handle_t *handle, |
| 2925 | struct file *file, | 2924 | struct inode *inode, |
| 2926 | u32 cpos, u32 old_cluster, | 2925 | u32 cpos, u32 old_cluster, |
| 2927 | u32 new_cluster, u32 new_len) | 2926 | u32 new_cluster, u32 new_len) |
| 2928 | { | 2927 | { |
| 2929 | int ret = 0, partial; | 2928 | int ret = 0, partial; |
| 2930 | struct inode *inode = file_inode(file); | 2929 | struct super_block *sb = inode->i_sb; |
| 2931 | struct ocfs2_caching_info *ci = INODE_CACHE(inode); | ||
| 2932 | struct super_block *sb = ocfs2_metadata_cache_get_super(ci); | ||
| 2933 | u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); | 2930 | u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); |
| 2934 | struct page *page; | 2931 | struct page *page; |
| 2935 | pgoff_t page_index; | 2932 | pgoff_t page_index; |
| @@ -2965,6 +2962,11 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
| 2965 | to = map_end & (PAGE_CACHE_SIZE - 1); | 2962 | to = map_end & (PAGE_CACHE_SIZE - 1); |
| 2966 | 2963 | ||
| 2967 | page = find_or_create_page(mapping, page_index, GFP_NOFS); | 2964 | page = find_or_create_page(mapping, page_index, GFP_NOFS); |
| 2965 | if (!page) { | ||
| 2966 | ret = -ENOMEM; | ||
| 2967 | mlog_errno(ret); | ||
| 2968 | break; | ||
| 2969 | } | ||
| 2968 | 2970 | ||
| 2969 | /* | 2971 | /* |
| 2970 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page | 2972 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page |
| @@ -2973,13 +2975,6 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
| 2973 | if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) | 2975 | if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) |
| 2974 | BUG_ON(PageDirty(page)); | 2976 | BUG_ON(PageDirty(page)); |
| 2975 | 2977 | ||
| 2976 | if (PageReadahead(page)) { | ||
| 2977 | page_cache_async_readahead(mapping, | ||
| 2978 | &file->f_ra, file, | ||
| 2979 | page, page_index, | ||
| 2980 | readahead_pages); | ||
| 2981 | } | ||
| 2982 | |||
| 2983 | if (!PageUptodate(page)) { | 2978 | if (!PageUptodate(page)) { |
| 2984 | ret = block_read_full_page(page, ocfs2_get_block); | 2979 | ret = block_read_full_page(page, ocfs2_get_block); |
| 2985 | if (ret) { | 2980 | if (ret) { |
| @@ -2999,7 +2994,8 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
| 2999 | } | 2994 | } |
| 3000 | } | 2995 | } |
| 3001 | 2996 | ||
| 3002 | ocfs2_map_and_dirty_page(inode, handle, from, to, | 2997 | ocfs2_map_and_dirty_page(inode, |
| 2998 | handle, from, to, | ||
| 3003 | page, 0, &new_block); | 2999 | page, 0, &new_block); |
| 3004 | mark_page_accessed(page); | 3000 | mark_page_accessed(page); |
| 3005 | unlock: | 3001 | unlock: |
| @@ -3015,12 +3011,11 @@ unlock: | |||
| 3015 | } | 3011 | } |
| 3016 | 3012 | ||
| 3017 | int ocfs2_duplicate_clusters_by_jbd(handle_t *handle, | 3013 | int ocfs2_duplicate_clusters_by_jbd(handle_t *handle, |
| 3018 | struct file *file, | 3014 | struct inode *inode, |
| 3019 | u32 cpos, u32 old_cluster, | 3015 | u32 cpos, u32 old_cluster, |
| 3020 | u32 new_cluster, u32 new_len) | 3016 | u32 new_cluster, u32 new_len) |
| 3021 | { | 3017 | { |
| 3022 | int ret = 0; | 3018 | int ret = 0; |
| 3023 | struct inode *inode = file_inode(file); | ||
| 3024 | struct super_block *sb = inode->i_sb; | 3019 | struct super_block *sb = inode->i_sb; |
| 3025 | struct ocfs2_caching_info *ci = INODE_CACHE(inode); | 3020 | struct ocfs2_caching_info *ci = INODE_CACHE(inode); |
| 3026 | int i, blocks = ocfs2_clusters_to_blocks(sb, new_len); | 3021 | int i, blocks = ocfs2_clusters_to_blocks(sb, new_len); |
| @@ -3145,7 +3140,7 @@ static int ocfs2_replace_clusters(handle_t *handle, | |||
| 3145 | 3140 | ||
| 3146 | /*If the old clusters is unwritten, no need to duplicate. */ | 3141 | /*If the old clusters is unwritten, no need to duplicate. */ |
| 3147 | if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) { | 3142 | if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) { |
| 3148 | ret = context->cow_duplicate_clusters(handle, context->file, | 3143 | ret = context->cow_duplicate_clusters(handle, context->inode, |
| 3149 | cpos, old, new, len); | 3144 | cpos, old, new, len); |
| 3150 | if (ret) { | 3145 | if (ret) { |
| 3151 | mlog_errno(ret); | 3146 | mlog_errno(ret); |
| @@ -3423,35 +3418,12 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context) | |||
| 3423 | return ret; | 3418 | return ret; |
| 3424 | } | 3419 | } |
| 3425 | 3420 | ||
| 3426 | static void ocfs2_readahead_for_cow(struct inode *inode, | ||
| 3427 | struct file *file, | ||
| 3428 | u32 start, u32 len) | ||
| 3429 | { | ||
| 3430 | struct address_space *mapping; | ||
| 3431 | pgoff_t index; | ||
| 3432 | unsigned long num_pages; | ||
| 3433 | int cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits; | ||
| 3434 | |||
| 3435 | if (!file) | ||
| 3436 | return; | ||
| 3437 | |||
| 3438 | mapping = file->f_mapping; | ||
| 3439 | num_pages = (len << cs_bits) >> PAGE_CACHE_SHIFT; | ||
| 3440 | if (!num_pages) | ||
| 3441 | num_pages = 1; | ||
| 3442 | |||
| 3443 | index = ((loff_t)start << cs_bits) >> PAGE_CACHE_SHIFT; | ||
| 3444 | page_cache_sync_readahead(mapping, &file->f_ra, file, | ||
| 3445 | index, num_pages); | ||
| 3446 | } | ||
| 3447 | |||
| 3448 | /* | 3421 | /* |
| 3449 | * Starting at cpos, try to CoW write_len clusters. Don't CoW | 3422 | * Starting at cpos, try to CoW write_len clusters. Don't CoW |
| 3450 | * past max_cpos. This will stop when it runs into a hole or an | 3423 | * past max_cpos. This will stop when it runs into a hole or an |
| 3451 | * unrefcounted extent. | 3424 | * unrefcounted extent. |
| 3452 | */ | 3425 | */ |
| 3453 | static int ocfs2_refcount_cow_hunk(struct inode *inode, | 3426 | static int ocfs2_refcount_cow_hunk(struct inode *inode, |
| 3454 | struct file *file, | ||
| 3455 | struct buffer_head *di_bh, | 3427 | struct buffer_head *di_bh, |
| 3456 | u32 cpos, u32 write_len, u32 max_cpos) | 3428 | u32 cpos, u32 write_len, u32 max_cpos) |
| 3457 | { | 3429 | { |
| @@ -3480,8 +3452,6 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, | |||
| 3480 | 3452 | ||
| 3481 | BUG_ON(cow_len == 0); | 3453 | BUG_ON(cow_len == 0); |
| 3482 | 3454 | ||
| 3483 | ocfs2_readahead_for_cow(inode, file, cow_start, cow_len); | ||
| 3484 | |||
| 3485 | context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); | 3455 | context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); |
| 3486 | if (!context) { | 3456 | if (!context) { |
| 3487 | ret = -ENOMEM; | 3457 | ret = -ENOMEM; |
| @@ -3503,7 +3473,6 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, | |||
| 3503 | context->ref_root_bh = ref_root_bh; | 3473 | context->ref_root_bh = ref_root_bh; |
| 3504 | context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page; | 3474 | context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page; |
| 3505 | context->get_clusters = ocfs2_di_get_clusters; | 3475 | context->get_clusters = ocfs2_di_get_clusters; |
| 3506 | context->file = file; | ||
| 3507 | 3476 | ||
| 3508 | ocfs2_init_dinode_extent_tree(&context->data_et, | 3477 | ocfs2_init_dinode_extent_tree(&context->data_et, |
| 3509 | INODE_CACHE(inode), di_bh); | 3478 | INODE_CACHE(inode), di_bh); |
| @@ -3532,7 +3501,6 @@ out: | |||
| 3532 | * clusters between cpos and cpos+write_len are safe to modify. | 3501 | * clusters between cpos and cpos+write_len are safe to modify. |
| 3533 | */ | 3502 | */ |
| 3534 | int ocfs2_refcount_cow(struct inode *inode, | 3503 | int ocfs2_refcount_cow(struct inode *inode, |
| 3535 | struct file *file, | ||
| 3536 | struct buffer_head *di_bh, | 3504 | struct buffer_head *di_bh, |
| 3537 | u32 cpos, u32 write_len, u32 max_cpos) | 3505 | u32 cpos, u32 write_len, u32 max_cpos) |
| 3538 | { | 3506 | { |
| @@ -3552,7 +3520,7 @@ int ocfs2_refcount_cow(struct inode *inode, | |||
| 3552 | num_clusters = write_len; | 3520 | num_clusters = write_len; |
| 3553 | 3521 | ||
| 3554 | if (ext_flags & OCFS2_EXT_REFCOUNTED) { | 3522 | if (ext_flags & OCFS2_EXT_REFCOUNTED) { |
| 3555 | ret = ocfs2_refcount_cow_hunk(inode, file, di_bh, cpos, | 3523 | ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos, |
| 3556 | num_clusters, max_cpos); | 3524 | num_clusters, max_cpos); |
| 3557 | if (ret) { | 3525 | if (ret) { |
| 3558 | mlog_errno(ret); | 3526 | mlog_errno(ret); |
