diff options
-rw-r--r-- | fs/xfs/xfs_alloc.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 33 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 36 |
3 files changed, 36 insertions, 37 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 879aa38ddd2a..e80dda3437d1 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -1477,8 +1477,10 @@ xfs_alloc_ag_vextent_small( | |||
1477 | /* | 1477 | /* |
1478 | * Can't allocate from the freelist for some reason. | 1478 | * Can't allocate from the freelist for some reason. |
1479 | */ | 1479 | */ |
1480 | else | 1480 | else { |
1481 | fbno = NULLAGBLOCK; | ||
1481 | flen = 0; | 1482 | flen = 0; |
1483 | } | ||
1482 | /* | 1484 | /* |
1483 | * Can't do the allocation, give up. | 1485 | * Can't do the allocation, give up. |
1484 | */ | 1486 | */ |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 32ab61d17ace..a68bc1f1a313 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1054,7 +1054,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1054 | xfs_da_node_entry_t *btree; | 1054 | xfs_da_node_entry_t *btree; |
1055 | xfs_dablk_t blkno; | 1055 | xfs_dablk_t blkno; |
1056 | int probe, span, max, error, retval; | 1056 | int probe, span, max, error, retval; |
1057 | xfs_dahash_t hashval; | 1057 | xfs_dahash_t hashval, btreehashval; |
1058 | xfs_da_args_t *args; | 1058 | xfs_da_args_t *args; |
1059 | 1059 | ||
1060 | args = state->args; | 1060 | args = state->args; |
@@ -1079,30 +1079,32 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1079 | return(error); | 1079 | return(error); |
1080 | } | 1080 | } |
1081 | curr = blk->bp->data; | 1081 | curr = blk->bp->data; |
1082 | ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || | 1082 | blk->magic = be16_to_cpu(curr->magic); |
1083 | be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC || | 1083 | ASSERT(blk->magic == XFS_DA_NODE_MAGIC || |
1084 | be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); | 1084 | blk->magic == XFS_DIR2_LEAFN_MAGIC || |
1085 | blk->magic == XFS_ATTR_LEAF_MAGIC); | ||
1085 | 1086 | ||
1086 | /* | 1087 | /* |
1087 | * Search an intermediate node for a match. | 1088 | * Search an intermediate node for a match. |
1088 | */ | 1089 | */ |
1089 | blk->magic = be16_to_cpu(curr->magic); | ||
1090 | if (blk->magic == XFS_DA_NODE_MAGIC) { | 1090 | if (blk->magic == XFS_DA_NODE_MAGIC) { |
1091 | node = blk->bp->data; | 1091 | node = blk->bp->data; |
1092 | blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); | 1092 | max = be16_to_cpu(node->hdr.count); |
1093 | btreehashval = node->btree[max-1].hashval; | ||
1094 | blk->hashval = be32_to_cpu(btreehashval); | ||
1093 | 1095 | ||
1094 | /* | 1096 | /* |
1095 | * Binary search. (note: small blocks will skip loop) | 1097 | * Binary search. (note: small blocks will skip loop) |
1096 | */ | 1098 | */ |
1097 | max = be16_to_cpu(node->hdr.count); | ||
1098 | probe = span = max / 2; | 1099 | probe = span = max / 2; |
1099 | hashval = args->hashval; | 1100 | hashval = args->hashval; |
1100 | for (btree = &node->btree[probe]; span > 4; | 1101 | for (btree = &node->btree[probe]; span > 4; |
1101 | btree = &node->btree[probe]) { | 1102 | btree = &node->btree[probe]) { |
1102 | span /= 2; | 1103 | span /= 2; |
1103 | if (be32_to_cpu(btree->hashval) < hashval) | 1104 | btreehashval = be32_to_cpu(btree->hashval); |
1105 | if (btreehashval < hashval) | ||
1104 | probe += span; | 1106 | probe += span; |
1105 | else if (be32_to_cpu(btree->hashval) > hashval) | 1107 | else if (btreehashval > hashval) |
1106 | probe -= span; | 1108 | probe -= span; |
1107 | else | 1109 | else |
1108 | break; | 1110 | break; |
@@ -1133,10 +1135,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1133 | blk->index = probe; | 1135 | blk->index = probe; |
1134 | blkno = be32_to_cpu(btree->before); | 1136 | blkno = be32_to_cpu(btree->before); |
1135 | } | 1137 | } |
1136 | } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { | 1138 | } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { |
1137 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); | 1139 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); |
1138 | break; | 1140 | break; |
1139 | } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { | 1141 | } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { |
1140 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); | 1142 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); |
1141 | break; | 1143 | break; |
1142 | } | 1144 | } |
@@ -1152,11 +1154,13 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1152 | if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { | 1154 | if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { |
1153 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, | 1155 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, |
1154 | &blk->index, state); | 1156 | &blk->index, state); |
1155 | } | 1157 | } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { |
1156 | else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { | ||
1157 | retval = xfs_attr_leaf_lookup_int(blk->bp, args); | 1158 | retval = xfs_attr_leaf_lookup_int(blk->bp, args); |
1158 | blk->index = args->index; | 1159 | blk->index = args->index; |
1159 | args->blkno = blk->blkno; | 1160 | args->blkno = blk->blkno; |
1161 | } else { | ||
1162 | ASSERT(0); | ||
1163 | return XFS_ERROR(EFSCORRUPTED); | ||
1160 | } | 1164 | } |
1161 | if (((retval == ENOENT) || (retval == ENOATTR)) && | 1165 | if (((retval == ENOENT) || (retval == ENOATTR)) && |
1162 | (blk->hashval == args->hashval)) { | 1166 | (blk->hashval == args->hashval)) { |
@@ -1166,8 +1170,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1166 | return(error); | 1170 | return(error); |
1167 | if (retval == 0) { | 1171 | if (retval == 0) { |
1168 | continue; | 1172 | continue; |
1169 | } | 1173 | } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { |
1170 | else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { | ||
1171 | /* path_shift() gives ENOENT */ | 1174 | /* path_shift() gives ENOENT */ |
1172 | retval = XFS_ERROR(ENOATTR); | 1175 | retval = XFS_ERROR(ENOATTR); |
1173 | } | 1176 | } |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 5a0b678956e0..e050987afe18 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -1976,7 +1976,10 @@ xfs_growfs_rt( | |||
1976 | if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, | 1976 | if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, |
1977 | mp->m_sb.sb_rsumino))) | 1977 | mp->m_sb.sb_rsumino))) |
1978 | return error; | 1978 | return error; |
1979 | nmp = NULL; | 1979 | /* |
1980 | * Allocate a new (fake) mount/sb. | ||
1981 | */ | ||
1982 | nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP); | ||
1980 | /* | 1983 | /* |
1981 | * Loop over the bitmap blocks. | 1984 | * Loop over the bitmap blocks. |
1982 | * We will do everything one bitmap block at a time. | 1985 | * We will do everything one bitmap block at a time. |
@@ -1987,10 +1990,6 @@ xfs_growfs_rt( | |||
1987 | ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); | 1990 | ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); |
1988 | bmbno < nrbmblocks; | 1991 | bmbno < nrbmblocks; |
1989 | bmbno++) { | 1992 | bmbno++) { |
1990 | /* | ||
1991 | * Allocate a new (fake) mount/sb. | ||
1992 | */ | ||
1993 | nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP); | ||
1994 | *nmp = *mp; | 1993 | *nmp = *mp; |
1995 | nsbp = &nmp->m_sb; | 1994 | nsbp = &nmp->m_sb; |
1996 | /* | 1995 | /* |
@@ -2018,13 +2017,13 @@ xfs_growfs_rt( | |||
2018 | cancelflags = 0; | 2017 | cancelflags = 0; |
2019 | if ((error = xfs_trans_reserve(tp, 0, | 2018 | if ((error = xfs_trans_reserve(tp, 0, |
2020 | XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0))) | 2019 | XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0))) |
2021 | goto error_exit; | 2020 | break; |
2022 | /* | 2021 | /* |
2023 | * Lock out other callers by grabbing the bitmap inode lock. | 2022 | * Lock out other callers by grabbing the bitmap inode lock. |
2024 | */ | 2023 | */ |
2025 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, | 2024 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, |
2026 | XFS_ILOCK_EXCL, &ip))) | 2025 | XFS_ILOCK_EXCL, &ip))) |
2027 | goto error_exit; | 2026 | break; |
2028 | ASSERT(ip == mp->m_rbmip); | 2027 | ASSERT(ip == mp->m_rbmip); |
2029 | /* | 2028 | /* |
2030 | * Update the bitmap inode's size. | 2029 | * Update the bitmap inode's size. |
@@ -2038,7 +2037,7 @@ xfs_growfs_rt( | |||
2038 | */ | 2037 | */ |
2039 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, | 2038 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, |
2040 | XFS_ILOCK_EXCL, &ip))) | 2039 | XFS_ILOCK_EXCL, &ip))) |
2041 | goto error_exit; | 2040 | break; |
2042 | ASSERT(ip == mp->m_rsumip); | 2041 | ASSERT(ip == mp->m_rsumip); |
2043 | /* | 2042 | /* |
2044 | * Update the summary inode's size. | 2043 | * Update the summary inode's size. |
@@ -2053,7 +2052,7 @@ xfs_growfs_rt( | |||
2053 | mp->m_rsumlevels != nmp->m_rsumlevels) { | 2052 | mp->m_rsumlevels != nmp->m_rsumlevels) { |
2054 | error = xfs_rtcopy_summary(mp, nmp, tp); | 2053 | error = xfs_rtcopy_summary(mp, nmp, tp); |
2055 | if (error) | 2054 | if (error) |
2056 | goto error_exit; | 2055 | break; |
2057 | } | 2056 | } |
2058 | /* | 2057 | /* |
2059 | * Update superblock fields. | 2058 | * Update superblock fields. |
@@ -2080,18 +2079,13 @@ xfs_growfs_rt( | |||
2080 | error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, | 2079 | error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, |
2081 | nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); | 2080 | nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); |
2082 | if (error) | 2081 | if (error) |
2083 | goto error_exit; | 2082 | break; |
2084 | /* | 2083 | /* |
2085 | * Mark more blocks free in the superblock. | 2084 | * Mark more blocks free in the superblock. |
2086 | */ | 2085 | */ |
2087 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, | 2086 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, |
2088 | nsbp->sb_rextents - sbp->sb_rextents); | 2087 | nsbp->sb_rextents - sbp->sb_rextents); |
2089 | /* | 2088 | /* |
2090 | * Free the fake mp structure. | ||
2091 | */ | ||
2092 | kmem_free(nmp, sizeof(*nmp)); | ||
2093 | nmp = NULL; | ||
2094 | /* | ||
2095 | * Update mp values into the real mp structure. | 2089 | * Update mp values into the real mp structure. |
2096 | */ | 2090 | */ |
2097 | mp->m_rsumlevels = nrsumlevels; | 2091 | mp->m_rsumlevels = nrsumlevels; |
@@ -2101,15 +2095,15 @@ xfs_growfs_rt( | |||
2101 | */ | 2095 | */ |
2102 | xfs_trans_commit(tp, 0, NULL); | 2096 | xfs_trans_commit(tp, 0, NULL); |
2103 | } | 2097 | } |
2104 | return 0; | 2098 | |
2099 | if (error) | ||
2100 | xfs_trans_cancel(tp, cancelflags); | ||
2105 | 2101 | ||
2106 | /* | 2102 | /* |
2107 | * Error paths come here. | 2103 | * Free the fake mp structure. |
2108 | */ | 2104 | */ |
2109 | error_exit: | 2105 | kmem_free(nmp, sizeof(*nmp)); |
2110 | if (nmp) | 2106 | |
2111 | kmem_free(nmp, sizeof(*nmp)); | ||
2112 | xfs_trans_cancel(tp, cancelflags); | ||
2113 | return error; | 2107 | return error; |
2114 | } | 2108 | } |
2115 | 2109 | ||