diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-23 16:33:07 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-23 16:33:07 -0500 |
| commit | 849254e9bba985e281526b57c02562c7a49a2fcf (patch) | |
| tree | a061f4de1c7b2836185e9d5bd4d7871c79692ca4 | |
| parent | 6f40334694dce047d43c6f2cce255b596da6de50 (diff) | |
| parent | 10cf1a02f444fdcd50be47cce3fa8bf08251dd9c (diff) | |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
ocfs2: Set i_nlink properly during reflink.
ocfs2: Add reflinked file's inode to inode hash eariler.
ocfs2: refcounttree.c cleanup.
ocfs2: Find proper end cpos for a leaf refcount block.
| -rw-r--r-- | fs/ocfs2/alloc.c | 10 | ||||
| -rw-r--r-- | fs/ocfs2/alloc.h | 5 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 5 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 150 |
4 files changed, 131 insertions, 39 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index fb4e672579b8..d17bdc718f74 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -1765,9 +1765,9 @@ set_and_inc: | |||
| 1765 | * | 1765 | * |
| 1766 | * The array index of the subtree root is passed back. | 1766 | * The array index of the subtree root is passed back. |
| 1767 | */ | 1767 | */ |
| 1768 | static int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, | 1768 | int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, |
| 1769 | struct ocfs2_path *left, | 1769 | struct ocfs2_path *left, |
| 1770 | struct ocfs2_path *right) | 1770 | struct ocfs2_path *right) |
| 1771 | { | 1771 | { |
| 1772 | int i = 0; | 1772 | int i = 0; |
| 1773 | 1773 | ||
| @@ -2872,8 +2872,8 @@ out: | |||
| 2872 | * This looks similar, but is subtly different to | 2872 | * This looks similar, but is subtly different to |
| 2873 | * ocfs2_find_cpos_for_left_leaf(). | 2873 | * ocfs2_find_cpos_for_left_leaf(). |
| 2874 | */ | 2874 | */ |
| 2875 | static int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, | 2875 | int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, |
| 2876 | struct ocfs2_path *path, u32 *cpos) | 2876 | struct ocfs2_path *path, u32 *cpos) |
| 2877 | { | 2877 | { |
| 2878 | int i, j, ret = 0; | 2878 | int i, j, ret = 0; |
| 2879 | u64 blkno; | 2879 | u64 blkno; |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 9c122d574464..1db4359ccb90 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
| @@ -317,4 +317,9 @@ int ocfs2_path_bh_journal_access(handle_t *handle, | |||
| 317 | int ocfs2_journal_access_path(struct ocfs2_caching_info *ci, | 317 | int ocfs2_journal_access_path(struct ocfs2_caching_info *ci, |
| 318 | handle_t *handle, | 318 | handle_t *handle, |
| 319 | struct ocfs2_path *path); | 319 | struct ocfs2_path *path); |
| 320 | int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, | ||
| 321 | struct ocfs2_path *path, u32 *cpos); | ||
| 322 | int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, | ||
| 323 | struct ocfs2_path *left, | ||
| 324 | struct ocfs2_path *right); | ||
| 320 | #endif /* OCFS2_ALLOC_H */ | 325 | #endif /* OCFS2_ALLOC_H */ |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f010b22b1c44..3e9b46002f22 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -2108,6 +2108,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
| 2108 | } | 2108 | } |
| 2109 | did_quota_inode = 1; | 2109 | did_quota_inode = 1; |
| 2110 | 2110 | ||
| 2111 | inode->i_nlink = 0; | ||
| 2111 | /* do the real work now. */ | 2112 | /* do the real work now. */ |
| 2112 | status = ocfs2_mknod_locked(osb, dir, inode, | 2113 | status = ocfs2_mknod_locked(osb, dir, inode, |
| 2113 | 0, &new_di_bh, parent_di_bh, handle, | 2114 | 0, &new_di_bh, parent_di_bh, handle, |
| @@ -2136,6 +2137,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
| 2136 | if (status < 0) | 2137 | if (status < 0) |
| 2137 | mlog_errno(status); | 2138 | mlog_errno(status); |
| 2138 | 2139 | ||
| 2140 | insert_inode_hash(inode); | ||
| 2139 | leave: | 2141 | leave: |
| 2140 | if (status < 0 && did_quota_inode) | 2142 | if (status < 0 && did_quota_inode) |
| 2141 | vfs_dq_free_inode(inode); | 2143 | vfs_dq_free_inode(inode); |
| @@ -2267,6 +2269,8 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, | |||
| 2267 | di = (struct ocfs2_dinode *)di_bh->b_data; | 2269 | di = (struct ocfs2_dinode *)di_bh->b_data; |
| 2268 | le32_add_cpu(&di->i_flags, -OCFS2_ORPHANED_FL); | 2270 | le32_add_cpu(&di->i_flags, -OCFS2_ORPHANED_FL); |
| 2269 | di->i_orphaned_slot = 0; | 2271 | di->i_orphaned_slot = 0; |
| 2272 | inode->i_nlink = 1; | ||
| 2273 | ocfs2_set_links_count(di, inode->i_nlink); | ||
| 2270 | ocfs2_journal_dirty(handle, di_bh); | 2274 | ocfs2_journal_dirty(handle, di_bh); |
| 2271 | 2275 | ||
| 2272 | status = ocfs2_add_entry(handle, dentry, inode, | 2276 | status = ocfs2_add_entry(handle, dentry, inode, |
| @@ -2284,7 +2288,6 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir, | |||
| 2284 | goto out_commit; | 2288 | goto out_commit; |
| 2285 | } | 2289 | } |
| 2286 | 2290 | ||
| 2287 | insert_inode_hash(inode); | ||
| 2288 | dentry->d_op = &ocfs2_dentry_ops; | 2291 | dentry->d_op = &ocfs2_dentry_ops; |
| 2289 | d_instantiate(dentry, inode); | 2292 | d_instantiate(dentry, inode); |
| 2290 | status = 0; | 2293 | status = 0; |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 30967e3f5e43..74db2be75dd6 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -276,7 +276,7 @@ static void ocfs2_erase_refcount_tree_from_list(struct ocfs2_super *osb, | |||
| 276 | spin_unlock(&osb->osb_lock); | 276 | spin_unlock(&osb->osb_lock); |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | void ocfs2_kref_remove_refcount_tree(struct kref *kref) | 279 | static void ocfs2_kref_remove_refcount_tree(struct kref *kref) |
| 280 | { | 280 | { |
| 281 | struct ocfs2_refcount_tree *tree = | 281 | struct ocfs2_refcount_tree *tree = |
| 282 | container_of(kref, struct ocfs2_refcount_tree, rf_getcnt); | 282 | container_of(kref, struct ocfs2_refcount_tree, rf_getcnt); |
| @@ -524,23 +524,6 @@ out: | |||
| 524 | return ret; | 524 | return ret; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | int ocfs2_lock_refcount_tree_by_inode(struct inode *inode, int rw, | ||
| 528 | struct ocfs2_refcount_tree **ret_tree, | ||
| 529 | struct buffer_head **ref_bh) | ||
| 530 | { | ||
| 531 | int ret; | ||
| 532 | u64 ref_blkno; | ||
| 533 | |||
| 534 | ret = ocfs2_get_refcount_block(inode, &ref_blkno); | ||
| 535 | if (ret) { | ||
| 536 | mlog_errno(ret); | ||
| 537 | return ret; | ||
| 538 | } | ||
| 539 | |||
| 540 | return ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb), ref_blkno, | ||
| 541 | rw, ret_tree, ref_bh); | ||
| 542 | } | ||
| 543 | |||
| 544 | void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb, | 527 | void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb, |
| 545 | struct ocfs2_refcount_tree *tree, int rw) | 528 | struct ocfs2_refcount_tree *tree, int rw) |
| 546 | { | 529 | { |
| @@ -969,6 +952,103 @@ out: | |||
| 969 | } | 952 | } |
| 970 | 953 | ||
| 971 | /* | 954 | /* |
| 955 | * Find the end range for a leaf refcount block indicated by | ||
| 956 | * el->l_recs[index].e_blkno. | ||
| 957 | */ | ||
| 958 | static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, | ||
| 959 | struct buffer_head *ref_root_bh, | ||
| 960 | struct ocfs2_extent_block *eb, | ||
| 961 | struct ocfs2_extent_list *el, | ||
| 962 | int index, u32 *cpos_end) | ||
| 963 | { | ||
| 964 | int ret, i, subtree_root; | ||
| 965 | u32 cpos; | ||
| 966 | u64 blkno; | ||
| 967 | struct super_block *sb = ocfs2_metadata_cache_get_super(ci); | ||
| 968 | struct ocfs2_path *left_path = NULL, *right_path = NULL; | ||
| 969 | struct ocfs2_extent_tree et; | ||
| 970 | struct ocfs2_extent_list *tmp_el; | ||
| 971 | |||
| 972 | if (index < le16_to_cpu(el->l_next_free_rec) - 1) { | ||
| 973 | /* | ||
| 974 | * We have a extent rec after index, so just use the e_cpos | ||
| 975 | * of the next extent rec. | ||
| 976 | */ | ||
| 977 | *cpos_end = le32_to_cpu(el->l_recs[index+1].e_cpos); | ||
| 978 | return 0; | ||
| 979 | } | ||
| 980 | |||
| 981 | if (!eb || (eb && !eb->h_next_leaf_blk)) { | ||
| 982 | /* | ||
| 983 | * We are the last extent rec, so any high cpos should | ||
| 984 | * be stored in this leaf refcount block. | ||
| 985 | */ | ||
| 986 | *cpos_end = UINT_MAX; | ||
| 987 | return 0; | ||
| 988 | } | ||
| 989 | |||
| 990 | /* | ||
| 991 | * If the extent block isn't the last one, we have to find | ||
| 992 | * the subtree root between this extent block and the next | ||
| 993 | * leaf extent block and get the corresponding e_cpos from | ||
| 994 | * the subroot. Otherwise we may corrupt the b-tree. | ||
| 995 | */ | ||
| 996 | ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh); | ||
| 997 | |||
| 998 | left_path = ocfs2_new_path_from_et(&et); | ||
| 999 | if (!left_path) { | ||
| 1000 | ret = -ENOMEM; | ||
| 1001 | mlog_errno(ret); | ||
| 1002 | goto out; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | cpos = le32_to_cpu(eb->h_list.l_recs[index].e_cpos); | ||
| 1006 | ret = ocfs2_find_path(ci, left_path, cpos); | ||
| 1007 | if (ret) { | ||
| 1008 | mlog_errno(ret); | ||
| 1009 | goto out; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | right_path = ocfs2_new_path_from_path(left_path); | ||
| 1013 | if (!right_path) { | ||
| 1014 | ret = -ENOMEM; | ||
| 1015 | mlog_errno(ret); | ||
| 1016 | goto out; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | ret = ocfs2_find_cpos_for_right_leaf(sb, left_path, &cpos); | ||
| 1020 | if (ret) { | ||
| 1021 | mlog_errno(ret); | ||
| 1022 | goto out; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | ret = ocfs2_find_path(ci, right_path, cpos); | ||
| 1026 | if (ret) { | ||
| 1027 | mlog_errno(ret); | ||
| 1028 | goto out; | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | subtree_root = ocfs2_find_subtree_root(&et, left_path, | ||
| 1032 | right_path); | ||
| 1033 | |||
| 1034 | tmp_el = left_path->p_node[subtree_root].el; | ||
| 1035 | blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; | ||
| 1036 | for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { | ||
| 1037 | if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { | ||
| 1038 | *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); | ||
| 1039 | break; | ||
| 1040 | } | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); | ||
| 1044 | |||
| 1045 | out: | ||
| 1046 | ocfs2_free_path(left_path); | ||
| 1047 | ocfs2_free_path(right_path); | ||
| 1048 | return ret; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | /* | ||
| 972 | * Given a cpos and len, try to find the refcount record which contains cpos. | 1052 | * Given a cpos and len, try to find the refcount record which contains cpos. |
| 973 | * 1. If cpos can be found in one refcount record, return the record. | 1053 | * 1. If cpos can be found in one refcount record, return the record. |
| 974 | * 2. If cpos can't be found, return a fake record which start from cpos | 1054 | * 2. If cpos can't be found, return a fake record which start from cpos |
| @@ -983,10 +1063,10 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, | |||
| 983 | struct buffer_head **ret_bh) | 1063 | struct buffer_head **ret_bh) |
| 984 | { | 1064 | { |
| 985 | int ret = 0, i, found; | 1065 | int ret = 0, i, found; |
| 986 | u32 low_cpos; | 1066 | u32 low_cpos, uninitialized_var(cpos_end); |
| 987 | struct ocfs2_extent_list *el; | 1067 | struct ocfs2_extent_list *el; |
| 988 | struct ocfs2_extent_rec *tmp, *rec = NULL; | 1068 | struct ocfs2_extent_rec *rec = NULL; |
| 989 | struct ocfs2_extent_block *eb; | 1069 | struct ocfs2_extent_block *eb = NULL; |
| 990 | struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL; | 1070 | struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL; |
| 991 | struct super_block *sb = ocfs2_metadata_cache_get_super(ci); | 1071 | struct super_block *sb = ocfs2_metadata_cache_get_super(ci); |
| 992 | struct ocfs2_refcount_block *rb = | 1072 | struct ocfs2_refcount_block *rb = |
| @@ -1034,12 +1114,16 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, | |||
| 1034 | } | 1114 | } |
| 1035 | } | 1115 | } |
| 1036 | 1116 | ||
| 1037 | /* adjust len when we have ocfs2_extent_rec after it. */ | 1117 | if (found) { |
| 1038 | if (found && i < le16_to_cpu(el->l_next_free_rec) - 1) { | 1118 | ret = ocfs2_get_refcount_cpos_end(ci, ref_root_bh, |
| 1039 | tmp = &el->l_recs[i+1]; | 1119 | eb, el, i, &cpos_end); |
| 1120 | if (ret) { | ||
| 1121 | mlog_errno(ret); | ||
| 1122 | goto out; | ||
| 1123 | } | ||
| 1040 | 1124 | ||
| 1041 | if (le32_to_cpu(tmp->e_cpos) < cpos + len) | 1125 | if (cpos_end < low_cpos + len) |
| 1042 | len = le32_to_cpu(tmp->e_cpos) - cpos; | 1126 | len = cpos_end - low_cpos; |
| 1043 | } | 1127 | } |
| 1044 | 1128 | ||
| 1045 | ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno), | 1129 | ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno), |
| @@ -1418,7 +1502,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, | |||
| 1418 | 1502 | ||
| 1419 | /* change old and new rl_used accordingly. */ | 1503 | /* change old and new rl_used accordingly. */ |
| 1420 | le16_add_cpu(&rl->rl_used, -num_moved); | 1504 | le16_add_cpu(&rl->rl_used, -num_moved); |
| 1421 | new_rl->rl_used = cpu_to_le32(num_moved); | 1505 | new_rl->rl_used = cpu_to_le16(num_moved); |
| 1422 | 1506 | ||
| 1423 | sort(&rl->rl_recs, le16_to_cpu(rl->rl_used), | 1507 | sort(&rl->rl_recs, le16_to_cpu(rl->rl_used), |
| 1424 | sizeof(struct ocfs2_refcount_rec), | 1508 | sizeof(struct ocfs2_refcount_rec), |
| @@ -1797,7 +1881,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle, | |||
| 1797 | recs_need++; | 1881 | recs_need++; |
| 1798 | 1882 | ||
| 1799 | /* If the leaf block don't have enough record, expand it. */ | 1883 | /* If the leaf block don't have enough record, expand it. */ |
| 1800 | if (le16_to_cpu(rf_list->rl_used) + recs_need > rf_list->rl_count) { | 1884 | if (le16_to_cpu(rf_list->rl_used) + recs_need > |
| 1885 | le16_to_cpu(rf_list->rl_count)) { | ||
| 1801 | struct ocfs2_refcount_rec tmp_rec; | 1886 | struct ocfs2_refcount_rec tmp_rec; |
| 1802 | u64 cpos = le64_to_cpu(orig_rec->r_cpos); | 1887 | u64 cpos = le64_to_cpu(orig_rec->r_cpos); |
| 1803 | len = le32_to_cpu(orig_rec->r_clusters); | 1888 | len = le32_to_cpu(orig_rec->r_clusters); |
| @@ -1859,7 +1944,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle, | |||
| 1859 | memcpy(tail_rec, orig_rec, sizeof(struct ocfs2_refcount_rec)); | 1944 | memcpy(tail_rec, orig_rec, sizeof(struct ocfs2_refcount_rec)); |
| 1860 | le64_add_cpu(&tail_rec->r_cpos, | 1945 | le64_add_cpu(&tail_rec->r_cpos, |
| 1861 | le32_to_cpu(tail_rec->r_clusters) - len); | 1946 | le32_to_cpu(tail_rec->r_clusters) - len); |
| 1862 | tail_rec->r_clusters = le32_to_cpu(len); | 1947 | tail_rec->r_clusters = cpu_to_le32(len); |
| 1863 | } | 1948 | } |
| 1864 | 1949 | ||
| 1865 | /* | 1950 | /* |
| @@ -3840,8 +3925,7 @@ static int ocfs2_add_refcounted_extent(struct inode *inode, | |||
| 3840 | } | 3925 | } |
| 3841 | 3926 | ||
| 3842 | ret = ocfs2_insert_extent(handle, et, cpos, | 3927 | ret = ocfs2_insert_extent(handle, et, cpos, |
| 3843 | cpu_to_le64(ocfs2_clusters_to_blocks(inode->i_sb, | 3928 | ocfs2_clusters_to_blocks(inode->i_sb, p_cluster), |
| 3844 | p_cluster)), | ||
| 3845 | num_clusters, ext_flags, meta_ac); | 3929 | num_clusters, ext_flags, meta_ac); |
| 3846 | if (ret) { | 3930 | if (ret) { |
| 3847 | mlog_errno(ret); | 3931 | mlog_errno(ret); |
| @@ -4253,8 +4337,8 @@ static int ocfs2_user_path_parent(const char __user *path, | |||
| 4253 | * @new_dentry: target dentry | 4337 | * @new_dentry: target dentry |
| 4254 | * @preserve: if true, preserve all file attributes | 4338 | * @preserve: if true, preserve all file attributes |
| 4255 | */ | 4339 | */ |
| 4256 | int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, | 4340 | static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, |
| 4257 | struct dentry *new_dentry, bool preserve) | 4341 | struct dentry *new_dentry, bool preserve) |
| 4258 | { | 4342 | { |
| 4259 | struct inode *inode = old_dentry->d_inode; | 4343 | struct inode *inode = old_dentry->d_inode; |
| 4260 | int error; | 4344 | int error; |
