diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-06-18 14:55:50 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-07-06 17:39:38 -0400 |
commit | 6775e24d9ccf6a48ebd1d31ca77db5ebfe00ce43 (patch) | |
tree | 55ec87daf1af1282f389f8481d9cc0431180c3a1 /fs/ufs | |
parent | 85416288bf730cffb61ab6ce8a7b97b17c73458f (diff) |
ufs_trunc_..indirect(): more massage towards unifying
Instead of manually checking that the array contains only zeroes,
find the position of the last non-zero (in __ufs_truncate(), where
we can conveniently do that) and use that to tell if there's
any non-zero in the array tail passed to ufs_trunc_...indirect().
The goal of all that clumsiness is to get fold these functions
together.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/inode.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 34d8dac4fe8b..e90266a221b8 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -1069,7 +1069,7 @@ next1: | |||
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | 1071 | ||
1072 | static void ufs_trunc_indirect(struct inode *inode, unsigned *offsets, void *p) | 1072 | static void ufs_trunc_indirect(struct inode *inode, unsigned *offsets, int depth2, void *p) |
1073 | { | 1073 | { |
1074 | struct super_block *sb = inode->i_sb; | 1074 | struct super_block *sb = inode->i_sb; |
1075 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 1075 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
@@ -1078,7 +1078,7 @@ static void ufs_trunc_indirect(struct inode *inode, unsigned *offsets, void *p) | |||
1078 | u64 tmp, frag_to_free = 0; | 1078 | u64 tmp, frag_to_free = 0; |
1079 | unsigned free_count = 0; | 1079 | unsigned free_count = 0; |
1080 | unsigned from = offsets ? *offsets : 0; | 1080 | unsigned from = offsets ? *offsets : 0; |
1081 | bool to_free = !offsets || !from; | 1081 | bool to_free = !offsets || !depth2; |
1082 | unsigned i; | 1082 | unsigned i; |
1083 | 1083 | ||
1084 | tmp = ufs_data_ptr_to_cpu(sb, p); | 1084 | tmp = ufs_data_ptr_to_cpu(sb, p); |
@@ -1135,14 +1135,14 @@ static void ufs_trunc_indirect(struct inode *inode, unsigned *offsets, void *p) | |||
1135 | ubh_brelse (ind_ubh); | 1135 | ubh_brelse (ind_ubh); |
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | static void ufs_trunc_dindirect(struct inode *inode, unsigned *offsets, void *p) | 1138 | static void ufs_trunc_dindirect(struct inode *inode, unsigned *offsets, int depth2, void *p) |
1139 | { | 1139 | { |
1140 | struct super_block *sb = inode->i_sb; | 1140 | struct super_block *sb = inode->i_sb; |
1141 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 1141 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
1142 | struct ufs_buffer_head *dind_bh; | 1142 | struct ufs_buffer_head *dind_bh; |
1143 | u64 tmp; | 1143 | u64 tmp; |
1144 | void *dind; | 1144 | void *dind; |
1145 | bool free_it = !offsets || !(offsets[0] || offsets[1]); | 1145 | bool free_it = !offsets || !depth2; |
1146 | unsigned dindirect_block = offsets ? *offsets++ : 0; | 1146 | unsigned dindirect_block = offsets ? *offsets++ : 0; |
1147 | unsigned i; | 1147 | unsigned i; |
1148 | 1148 | ||
@@ -1162,7 +1162,7 @@ static void ufs_trunc_dindirect(struct inode *inode, unsigned *offsets, void *p) | |||
1162 | tmp = ufs_data_ptr_to_cpu(sb, dind); | 1162 | tmp = ufs_data_ptr_to_cpu(sb, dind); |
1163 | if (!tmp) | 1163 | if (!tmp) |
1164 | continue; | 1164 | continue; |
1165 | ufs_trunc_indirect(inode, offsets, dind); | 1165 | ufs_trunc_indirect(inode, offsets, depth2 - 1, dind); |
1166 | ubh_mark_buffer_dirty(dind_bh); | 1166 | ubh_mark_buffer_dirty(dind_bh); |
1167 | } | 1167 | } |
1168 | 1168 | ||
@@ -1182,7 +1182,7 @@ static void ufs_trunc_dindirect(struct inode *inode, unsigned *offsets, void *p) | |||
1182 | ubh_brelse (dind_bh); | 1182 | ubh_brelse (dind_bh); |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | static void ufs_trunc_tindirect(struct inode *inode, unsigned *offsets) | 1185 | static void ufs_trunc_tindirect(struct inode *inode, unsigned *offsets, int depth2) |
1186 | { | 1186 | { |
1187 | struct super_block *sb = inode->i_sb; | 1187 | struct super_block *sb = inode->i_sb; |
1188 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 1188 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
@@ -1190,7 +1190,7 @@ static void ufs_trunc_tindirect(struct inode *inode, unsigned *offsets) | |||
1190 | struct ufs_buffer_head * tind_bh; | 1190 | struct ufs_buffer_head * tind_bh; |
1191 | u64 tmp; | 1191 | u64 tmp; |
1192 | void *tind, *p; | 1192 | void *tind, *p; |
1193 | bool free_it = !offsets || !(offsets[0] || offsets[1] || offsets[2]); | 1193 | bool free_it = !offsets || !depth2; |
1194 | unsigned tindirect_block = offsets ? *offsets++ : 0; | 1194 | unsigned tindirect_block = offsets ? *offsets++ : 0; |
1195 | unsigned i; | 1195 | unsigned i; |
1196 | 1196 | ||
@@ -1207,7 +1207,7 @@ static void ufs_trunc_tindirect(struct inode *inode, unsigned *offsets) | |||
1207 | 1207 | ||
1208 | for (i = tindirect_block ; i < uspi->s_apb ; i++, offsets = NULL) { | 1208 | for (i = tindirect_block ; i < uspi->s_apb ; i++, offsets = NULL) { |
1209 | tind = ubh_get_data_ptr(uspi, tind_bh, i); | 1209 | tind = ubh_get_data_ptr(uspi, tind_bh, i); |
1210 | ufs_trunc_dindirect(inode, offsets, tind); | 1210 | ufs_trunc_dindirect(inode, offsets, depth2 - 1, tind); |
1211 | ubh_mark_buffer_dirty(tind_bh); | 1211 | ubh_mark_buffer_dirty(tind_bh); |
1212 | } | 1212 | } |
1213 | if (free_it) { | 1213 | if (free_it) { |
@@ -1303,31 +1303,40 @@ static void __ufs_truncate_blocks(struct inode *inode) | |||
1303 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 1303 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
1304 | unsigned offsets[4]; | 1304 | unsigned offsets[4]; |
1305 | int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets); | 1305 | int depth = ufs_block_to_path(inode, DIRECT_BLOCK, offsets); |
1306 | int depth2; | ||
1307 | |||
1308 | if (!depth) | ||
1309 | return; | ||
1310 | |||
1311 | /* find the last non-zero in offsets[] */ | ||
1312 | for (depth2 = depth - 1; depth2; depth2--) | ||
1313 | if (offsets[depth2]) | ||
1314 | break; | ||
1306 | 1315 | ||
1307 | mutex_lock(&ufsi->truncate_mutex); | 1316 | mutex_lock(&ufsi->truncate_mutex); |
1308 | switch (depth) { | 1317 | switch (depth) { |
1309 | case 1: | 1318 | case 1: |
1310 | ufs_trunc_direct(inode); | 1319 | ufs_trunc_direct(inode); |
1311 | ufs_trunc_indirect(inode, NULL, | 1320 | ufs_trunc_indirect(inode, NULL, 0, |
1312 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_IND_BLOCK)); | 1321 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_IND_BLOCK)); |
1313 | ufs_trunc_dindirect(inode, NULL, | 1322 | ufs_trunc_dindirect(inode, NULL, 0, |
1314 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); | 1323 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); |
1315 | ufs_trunc_tindirect(inode, NULL); | 1324 | ufs_trunc_tindirect(inode, NULL, 0); |
1316 | break; | 1325 | break; |
1317 | case 2: | 1326 | case 2: |
1318 | ufs_trunc_indirect(inode, offsets + 1, | 1327 | ufs_trunc_indirect(inode, offsets + 1, depth2, |
1319 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_IND_BLOCK)); | 1328 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_IND_BLOCK)); |
1320 | ufs_trunc_dindirect(inode, NULL, | 1329 | ufs_trunc_dindirect(inode, NULL, 0, |
1321 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); | 1330 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); |
1322 | ufs_trunc_tindirect(inode, NULL); | 1331 | ufs_trunc_tindirect(inode, NULL, 0); |
1323 | break; | 1332 | break; |
1324 | case 3: | 1333 | case 3: |
1325 | ufs_trunc_dindirect(inode, offsets + 1, | 1334 | ufs_trunc_dindirect(inode, offsets + 1, depth2, |
1326 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); | 1335 | ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); |
1327 | ufs_trunc_tindirect(inode, NULL); | 1336 | ufs_trunc_tindirect(inode, NULL, 0); |
1328 | break; | 1337 | break; |
1329 | case 4: | 1338 | case 4: |
1330 | ufs_trunc_tindirect(inode, offsets + 1); | 1339 | ufs_trunc_tindirect(inode, offsets + 1, depth2); |
1331 | } | 1340 | } |
1332 | ufsi->i_lastfrag = DIRECT_FRAGMENT; | 1341 | ufsi->i_lastfrag = DIRECT_FRAGMENT; |
1333 | mutex_unlock(&ufsi->truncate_mutex); | 1342 | mutex_unlock(&ufsi->truncate_mutex); |