aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-06-18 19:13:02 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-07-06 17:39:47 -0400
commit7b4e4f7f815db0059150a12542b28c787e19c0d7 (patch)
tree42b9d54c8e503a16274caef849bc21ad7802a211 /fs/ufs
parent6aab6dd37946d0d592105872bd533bb7d2931f3f (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.c52
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
1127static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2, int depth, void *p) 1127static 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,