aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-06-18 13:45:07 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-07-06 17:39:33 -0400
commit18ca51d8211065f10672374336cd08d495968c73 (patch)
tree9be8fb4d8d961ecee2d7195b3eb38e49c2c4f311 /fs
parent31cd043e1a09c579c4cd38ea432200fbeae6af1f (diff)
ufs_trunc_tindirect(): pass the number of blocks to keep
IOW, the distance of cutoff from the begining of the branch (in blocks). That (and the fact that block just prior to cutoff is guaranteed to be present) allows to tell whether to free triple indirect block just by looking at the offset. While we are at it, using u64 for index in the block is wrong - those should be unsigned int. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/ufs/inode.c28
1 files changed, 11 insertions, 17 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index afb0f32b921c..5b3f1c44d4b0 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -1208,19 +1208,17 @@ static void ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
1208 UFSD("EXIT: ino %lu\n", inode->i_ino); 1208 UFSD("EXIT: ino %lu\n", inode->i_ino);
1209} 1209}
1210 1210
1211static void ufs_trunc_tindirect(struct inode *inode) 1211static void ufs_trunc_tindirect(struct inode *inode, u64 offset)
1212{ 1212{
1213 struct super_block *sb = inode->i_sb; 1213 struct super_block *sb = inode->i_sb;
1214 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; 1214 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
1215 struct ufs_inode_info *ufsi = UFS_I(inode); 1215 struct ufs_inode_info *ufsi = UFS_I(inode);
1216 struct ufs_buffer_head * tind_bh; 1216 struct ufs_buffer_head * tind_bh;
1217 u64 tindirect_block, tmp, i; 1217 u64 tmp;
1218 void *tind, *p; 1218 void *tind, *p;
1219 1219 bool free_it = !offset;
1220 UFSD("ENTER: ino %lu\n", inode->i_ino); 1220 unsigned tindirect_block = offset >> uspi->s_2apbshift;
1221 1221 unsigned i;
1222 tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb))
1223 ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0;
1224 1222
1225 p = ufs_get_direct_data_ptr(uspi, ufsi, UFS_TIND_BLOCK); 1223 p = ufs_get_direct_data_ptr(uspi, ufsi, UFS_TIND_BLOCK);
1226 if (!(tmp = ufs_data_ptr_to_cpu(sb, p))) 1224 if (!(tmp = ufs_data_ptr_to_cpu(sb, p)))
@@ -1239,11 +1237,7 @@ static void ufs_trunc_tindirect(struct inode *inode)
1239 uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); 1237 uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind);
1240 ubh_mark_buffer_dirty(tind_bh); 1238 ubh_mark_buffer_dirty(tind_bh);
1241 } 1239 }
1242 for (i = 0; i < uspi->s_apb; i++) 1240 if (free_it) {
1243 if (!ufs_is_data_ptr_zero(uspi,
1244 ubh_get_data_ptr(uspi, tind_bh, i)))
1245 break;
1246 if (i >= uspi->s_apb) {
1247 tmp = ufs_data_ptr_to_cpu(sb, p); 1241 tmp = ufs_data_ptr_to_cpu(sb, p);
1248 write_seqlock(&ufsi->meta_lock); 1242 write_seqlock(&ufsi->meta_lock);
1249 ufs_data_ptr_clear(uspi, p); 1243 ufs_data_ptr_clear(uspi, p);
@@ -1252,13 +1246,11 @@ static void ufs_trunc_tindirect(struct inode *inode)
1252 ubh_bforget(tind_bh); 1246 ubh_bforget(tind_bh);
1253 ufs_free_blocks(inode, tmp, uspi->s_fpb); 1247 ufs_free_blocks(inode, tmp, uspi->s_fpb);
1254 mark_inode_dirty(inode); 1248 mark_inode_dirty(inode);
1255 tind_bh = NULL; 1249 return;
1256 } 1250 }
1257 if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) 1251 if (IS_SYNC(inode) && ubh_buffer_dirty(tind_bh))
1258 ubh_sync_block(tind_bh); 1252 ubh_sync_block(tind_bh);
1259 ubh_brelse (tind_bh); 1253 ubh_brelse (tind_bh);
1260
1261 UFSD("EXIT: ino %lu\n", inode->i_ino);
1262} 1254}
1263 1255
1264static int ufs_alloc_lastblock(struct inode *inode, loff_t size) 1256static int ufs_alloc_lastblock(struct inode *inode, loff_t size)
@@ -1349,8 +1341,10 @@ static void __ufs_truncate_blocks(struct inode *inode)
1349 case 3: 1341 case 3:
1350 ufs_trunc_dindirect(inode, UFS_IND_BLOCK + uspi->s_apb, 1342 ufs_trunc_dindirect(inode, UFS_IND_BLOCK + uspi->s_apb,
1351 ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK)); 1343 ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK));
1344 ufs_trunc_tindirect(inode, 0);
1345 break;
1352 case 4: 1346 case 4:
1353 ufs_trunc_tindirect(inode); 1347 ufs_trunc_tindirect(inode, DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb);
1354 } 1348 }
1355 ufsi->i_lastfrag = DIRECT_FRAGMENT; 1349 ufsi->i_lastfrag = DIRECT_FRAGMENT;
1356 mutex_unlock(&ufsi->truncate_mutex); 1350 mutex_unlock(&ufsi->truncate_mutex);