diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-06-18 19:13:02 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-07-06 17:39:47 -0400 |
commit | 7b4e4f7f815db0059150a12542b28c787e19c0d7 (patch) | |
tree | 42b9d54c8e503a16274caef849bc21ad7802a211 /fs/ufs | |
parent | 6aab6dd37946d0d592105872bd533bb7d2931f3f (diff) |
ufs_trunc_branch(): kill recursion
turn recursion into a pair of loops
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/inode.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index dac81c318da7..314caad56d83 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -1124,34 +1124,14 @@ static void free_full_branch(struct inode *inode, int depth, void *p) | |||
1124 | mark_inode_dirty(inode); | 1124 | mark_inode_dirty(inode); |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2, int depth, void *p) | 1127 | static void free_branch_tail(struct inode *inode, unsigned from, struct ufs_buffer_head *ubh, int depth) |
1128 | { | 1128 | { |
1129 | struct super_block *sb = inode->i_sb; | 1129 | struct super_block *sb = inode->i_sb; |
1130 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 1130 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
1131 | struct ufs_inode_info *ufsi = UFS_I(inode); | ||
1132 | struct ufs_buffer_head *ubh; | ||
1133 | u64 tmp; | ||
1134 | unsigned from = *offsets++; | ||
1135 | unsigned i; | 1131 | unsigned i; |
1136 | 1132 | ||
1137 | tmp = ufs_data_ptr_to_cpu(sb, p); | ||
1138 | if (!tmp) | ||
1139 | return; | ||
1140 | ubh = ubh_bread (sb, tmp, uspi->s_bsize); | ||
1141 | if (!ubh) { | ||
1142 | write_seqlock(&ufsi->meta_lock); | ||
1143 | ufs_data_ptr_clear(uspi, p); | ||
1144 | write_sequnlock(&ufsi->meta_lock); | ||
1145 | return; | ||
1146 | } | ||
1147 | |||
1148 | if (--depth2) { | ||
1149 | void *ind = ubh_get_data_ptr(uspi, ubh, from++); | ||
1150 | ufs_trunc_branch(inode, offsets, depth2, depth - 1, ind); | ||
1151 | ubh_mark_buffer_dirty(ubh); | ||
1152 | } | ||
1153 | if (--depth) { | 1133 | if (--depth) { |
1154 | for (i = from ; i < uspi->s_apb ; i++) { | 1134 | for (i = from; i < uspi->s_apb ; i++) { |
1155 | void *ind = ubh_get_data_ptr(uspi, ubh, i); | 1135 | void *ind = ubh_get_data_ptr(uspi, ubh, i); |
1156 | free_full_branch(inode, depth, ind); | 1136 | free_full_branch(inode, depth, ind); |
1157 | ubh_mark_buffer_dirty(ubh); | 1137 | ubh_mark_buffer_dirty(ubh); |
@@ -1161,7 +1141,7 @@ static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2, | |||
1161 | 1141 | ||
1162 | for (i = from; i < uspi->s_apb; i++) { | 1142 | for (i = from; i < uspi->s_apb; i++) { |
1163 | void *ind = ubh_get_data_ptr(uspi, ubh, i); | 1143 | void *ind = ubh_get_data_ptr(uspi, ubh, i); |
1164 | tmp = ufs_data_ptr_to_cpu(sb, ind); | 1144 | u64 tmp = ufs_data_ptr_to_cpu(sb, ind); |
1165 | if (!tmp) | 1145 | if (!tmp) |
1166 | continue; | 1146 | continue; |
1167 | 1147 | ||
@@ -1258,6 +1238,9 @@ static void __ufs_truncate_blocks(struct inode *inode) | |||
1258 | int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets); | 1238 | int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets); |
1259 | int depth2; | 1239 | int depth2; |
1260 | unsigned i; | 1240 | unsigned i; |
1241 | struct ufs_buffer_head *ubh[3]; | ||
1242 | void *p; | ||
1243 | u64 block; | ||
1261 | 1244 | ||
1262 | if (!depth) | 1245 | if (!depth) |
1263 | return; | 1246 | return; |
@@ -1272,9 +1255,26 @@ static void __ufs_truncate_blocks(struct inode *inode) | |||
1272 | ufs_trunc_direct(inode); | 1255 | ufs_trunc_direct(inode); |
1273 | offsets[0] = UFS_IND_BLOCK; | 1256 | offsets[0] = UFS_IND_BLOCK; |
1274 | } else { | 1257 | } else { |
1275 | if (depth2) | 1258 | /* get the blocks that should be partially emptied */ |
1276 | ufs_trunc_branch(inode, offsets + 1, depth2, depth - 1, | 1259 | p = ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]); |
1277 | ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]++)); | 1260 | for (i = 0; i < depth2; i++) { |
1261 | offsets[i]++; /* next branch is fully freed */ | ||
1262 | block = ufs_data_ptr_to_cpu(sb, p); | ||
1263 | if (!block) | ||
1264 | break; | ||
1265 | ubh[i] = ubh_bread(sb, block, uspi->s_bsize); | ||
1266 | if (!ubh[i]) { | ||
1267 | write_seqlock(&ufsi->meta_lock); | ||
1268 | ufs_data_ptr_clear(uspi, p); | ||
1269 | write_sequnlock(&ufsi->meta_lock); | ||
1270 | break; | ||
1271 | } | ||
1272 | p = ubh_get_data_ptr(uspi, ubh[i], offsets[i + 1]); | ||
1273 | } | ||
1274 | while (i--) { | ||
1275 | ubh_mark_buffer_dirty(ubh[i]); | ||
1276 | free_branch_tail(inode, offsets[i + 1], ubh[i], depth - i - 1); | ||
1277 | } | ||
1278 | } | 1278 | } |
1279 | for (i = offsets[0]; i <= UFS_TIND_BLOCK; i++) { | 1279 | for (i = offsets[0]; i <= UFS_TIND_BLOCK; i++) { |
1280 | free_full_branch(inode, i - UFS_IND_BLOCK + 1, | 1280 | free_full_branch(inode, i - UFS_IND_BLOCK + 1, |