aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_alloc.c4
-rw-r--r--fs/xfs/xfs_da_btree.c33
-rw-r--r--fs/xfs/xfs_rtalloc.c36
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 */
2109error_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