summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-06-18 14:36:31 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-07-06 17:39:37 -0400
commit85416288bf730cffb61ab6ce8a7b97b17c73458f (patch)
tree12425e1a68e71d9a1070807d818a8b1d51268aeb
parent7a4fdda72451f094374324a552be9fc7de8f3e8d (diff)
downloadlinux-85416288bf730cffb61ab6ce8a7b97b17c73458f.tar.bz2
ufs_trunc_...indirect(): pass the array of indices instead of offsets
rather than bitslicing the offset just formed as sum of shifted indices, pass the array of those indices itself. NULL is used as equivalent of "all zeroes" (== free the entire branch). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ufs/inode.c50
1 files changed, 22 insertions, 28 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index c2544d62adf2..34d8dac4fe8b 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -1069,7 +1069,7 @@ next1:
}
-static void ufs_trunc_indirect(struct inode *inode, unsigned from, void *p)
+static void ufs_trunc_indirect(struct inode *inode, unsigned *offsets, void *p)
{
struct super_block *sb = inode->i_sb;
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
@@ -1077,7 +1077,8 @@ static void ufs_trunc_indirect(struct inode *inode, unsigned from, void *p)
void *ind;
u64 tmp, frag_to_free = 0;
unsigned free_count = 0;
- bool to_free = !from;
+ unsigned from = offsets ? *offsets : 0;
+ bool to_free = !offsets || !from;
unsigned i;
tmp = ufs_data_ptr_to_cpu(sb, p);
@@ -1134,16 +1135,15 @@ static void ufs_trunc_indirect(struct inode *inode, unsigned from, void *p)
ubh_brelse (ind_ubh);
}
-static void ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
+static void ufs_trunc_dindirect(struct inode *inode, unsigned *offsets, void *p)
{
struct super_block *sb = inode->i_sb;
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
struct ufs_buffer_head *dind_bh;
u64 tmp;
void *dind;
- bool free_it = !offset;
- unsigned dindirect_block = offset >> uspi->s_apbshift;
- unsigned from = offset & uspi->s_apbmask;
+ bool free_it = !offsets || !(offsets[0] || offsets[1]);
+ unsigned dindirect_block = offsets ? *offsets++ : 0;
unsigned i;
tmp = ufs_data_ptr_to_cpu(sb, p);
@@ -1157,12 +1157,12 @@ static void ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
return;
}
- for (i = dindirect_block ; i < uspi->s_apb ; i++, from = 0) {
+ for (i = dindirect_block ; i < uspi->s_apb ; i++, offsets = NULL) {
dind = ubh_get_data_ptr(uspi, dind_bh, i);
tmp = ufs_data_ptr_to_cpu(sb, dind);
if (!tmp)
continue;
- ufs_trunc_indirect(inode, from, dind);
+ ufs_trunc_indirect(inode, offsets, dind);
ubh_mark_buffer_dirty(dind_bh);
}
@@ -1182,7 +1182,7 @@ static void ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p)
ubh_brelse (dind_bh);
}
-static void ufs_trunc_tindirect(struct inode *inode, u64 offset)
+static void ufs_trunc_tindirect(struct inode *inode, unsigned *offsets)
{
struct super_block *sb = inode->i_sb;
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
@@ -1190,12 +1190,10 @@ static void ufs_trunc_tindirect(struct inode *inode, u64 offset)
struct ufs_buffer_head * tind_bh;
u64 tmp;
void *tind, *p;
- bool free_it = !offset;
- unsigned tindirect_block = offset >> uspi->s_2apbshift;
+ bool free_it = !offsets || !(offsets[0] || offsets[1] || offsets[2]);
+ unsigned tindirect_block = offsets ? *offsets++ : 0;
unsigned i;
- offset -= tindirect_block << uspi->s_2apbshift;
-
p = ufs_get_direct_data_ptr(uspi, ufsi, UFS_TIND_BLOCK);
if (!(tmp = ufs_data_ptr_to_cpu(sb, p)))
return;
@@ -1207,9 +1205,9 @@ static void ufs_trunc_tindirect(struct inode *inode, u64 offset)
return;
}
- for (i = tindirect_block ; i < uspi->s_apb ; i++, offset = 0) {
+ for (i = tindirect_block ; i < uspi->s_apb ; i++, offsets = NULL) {
tind = ubh_get_data_ptr(uspi, tind_bh, i);
- ufs_trunc_dindirect(inode, offset, tind);
+ ufs_trunc_dindirect(inode, offsets, tind);
ubh_mark_buffer_dirty(tind_bh);
}
if (free_it) {
@@ -1310,30 +1308,26 @@ static void __ufs_truncate_blocks(struct inode *inode)
switch (depth) {
case 1:
ufs_trunc_direct(inode);
- ufs_trunc_indirect(inode, 0,
+ ufs_trunc_indirect(inode, NULL,
ufs_get_direct_data_ptr(uspi, ufsi, UFS_IND_BLOCK));
- ufs_trunc_dindirect(inode, 0,
+ ufs_trunc_dindirect(inode, NULL,
ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK));
- ufs_trunc_tindirect(inode, 0);
+ ufs_trunc_tindirect(inode, NULL);
break;
case 2:
- ufs_trunc_indirect(inode, offsets[1],
+ ufs_trunc_indirect(inode, offsets + 1,
ufs_get_direct_data_ptr(uspi, ufsi, UFS_IND_BLOCK));
- ufs_trunc_dindirect(inode, 0,
+ ufs_trunc_dindirect(inode, NULL,
ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK));
- ufs_trunc_tindirect(inode, 0);
+ ufs_trunc_tindirect(inode, NULL);
break;
case 3:
- ufs_trunc_dindirect(inode,
- (offsets[1] << uspi->s_apbshift) + offsets[2],
+ ufs_trunc_dindirect(inode, offsets + 1,
ufs_get_direct_data_ptr(uspi, ufsi, UFS_DIND_BLOCK));
- ufs_trunc_tindirect(inode, 0);
+ ufs_trunc_tindirect(inode, NULL);
break;
case 4:
- ufs_trunc_tindirect(inode,
- (offsets[1] << uspi->s_2apbshift) +
- (offsets[2] << uspi->s_apbshift) +
- offsets[3]);
+ ufs_trunc_tindirect(inode, offsets + 1);
}
ufsi->i_lastfrag = DIRECT_FRAGMENT;
mutex_unlock(&ufsi->truncate_mutex);