aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-06-18 17:11:49 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-07-06 17:39:45 -0400
commit6d1ebbca2b2fe516ff5f279848cffbd23d2b0270 (patch)
tree777236223de7601dd0e18e0e96ba0c2dcf1a28d7 /fs/ufs
parenta138b4b688c10eb82044451b81534c382d1cddbd (diff)
split ufs_truncate_branch() into full- and partial-branch variants
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ufs')
-rw-r--r--fs/ufs/inode.c74
1 files changed, 58 insertions, 16 deletions
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 39de7782b7c5..c06556558c9b 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -1070,6 +1070,60 @@ next1:
1070 UFSD("EXIT: ino %lu\n", inode->i_ino); 1070 UFSD("EXIT: ino %lu\n", inode->i_ino);
1071} 1071}
1072 1072
1073static void free_full_branch(struct inode *inode, int depth, void *p)
1074{
1075 struct super_block *sb = inode->i_sb;
1076 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
1077 struct ufs_inode_info *ufsi = UFS_I(inode);
1078 struct ufs_buffer_head *ubh;
1079 u64 tmp;
1080 unsigned i;
1081
1082 tmp = ufs_data_ptr_to_cpu(sb, p);
1083 if (!tmp)
1084 return;
1085 ubh = ubh_bread (sb, tmp, uspi->s_bsize);
1086 if (!ubh) {
1087 write_seqlock(&ufsi->meta_lock);
1088 ufs_data_ptr_clear(uspi, p);
1089 write_sequnlock(&ufsi->meta_lock);
1090 return;
1091 }
1092
1093 if (--depth) {
1094 for (i = 0 ; i < uspi->s_apb ; i++) {
1095 void *ind = ubh_get_data_ptr(uspi, ubh, i);
1096 free_full_branch(inode, depth, ind);
1097 ubh_mark_buffer_dirty(ubh);
1098 }
1099 } else {
1100 struct to_free ctx = {.inode = inode};
1101
1102 for (i = 0; i < uspi->s_apb; i++) {
1103 void *ind = ubh_get_data_ptr(uspi, ubh, i);
1104 tmp = ufs_data_ptr_to_cpu(sb, ind);
1105 if (!tmp)
1106 continue;
1107
1108 write_seqlock(&UFS_I(inode)->meta_lock);
1109 ufs_data_ptr_clear(uspi, ind);
1110 write_sequnlock(&UFS_I(inode)->meta_lock);
1111 ubh_mark_buffer_dirty(ubh);
1112 free_data(&ctx, tmp, uspi->s_fpb);
1113 mark_inode_dirty(inode);
1114 }
1115 free_data(&ctx, 0, 0);
1116 }
1117 tmp = ufs_data_ptr_to_cpu(sb, p);
1118 write_seqlock(&ufsi->meta_lock);
1119 ufs_data_ptr_clear(uspi, p);
1120 write_sequnlock(&ufsi->meta_lock);
1121
1122 ubh_bforget(ubh);
1123 ufs_free_blocks(inode, tmp, uspi->s_fpb);
1124 mark_inode_dirty(inode);
1125}
1126
1073static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2, int depth, void *p) 1127static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2, int depth, void *p)
1074{ 1128{
1075 struct super_block *sb = inode->i_sb; 1129 struct super_block *sb = inode->i_sb;
@@ -1077,8 +1131,7 @@ static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2,
1077 struct ufs_inode_info *ufsi = UFS_I(inode); 1131 struct ufs_inode_info *ufsi = UFS_I(inode);
1078 struct ufs_buffer_head *ubh; 1132 struct ufs_buffer_head *ubh;
1079 u64 tmp; 1133 u64 tmp;
1080 bool free_it = !offsets; 1134 unsigned from = *offsets++;
1081 unsigned from = offsets ? *offsets++ : 0;
1082 unsigned i; 1135 unsigned i;
1083 1136
1084 tmp = ufs_data_ptr_to_cpu(sb, p); 1137 tmp = ufs_data_ptr_to_cpu(sb, p);
@@ -1093,14 +1146,14 @@ static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2,
1093 } 1146 }
1094 1147
1095 if (--depth) { 1148 if (--depth) {
1096 if (offsets && --depth2) { 1149 if (--depth2) {
1097 void *ind = ubh_get_data_ptr(uspi, ubh, from++); 1150 void *ind = ubh_get_data_ptr(uspi, ubh, from++);
1098 ufs_trunc_branch(inode, offsets, depth2, depth, ind); 1151 ufs_trunc_branch(inode, offsets, depth2, depth, ind);
1099 ubh_mark_buffer_dirty(ubh); 1152 ubh_mark_buffer_dirty(ubh);
1100 } 1153 }
1101 for (i = from ; i < uspi->s_apb ; i++) { 1154 for (i = from ; i < uspi->s_apb ; i++) {
1102 void *ind = ubh_get_data_ptr(uspi, ubh, i); 1155 void *ind = ubh_get_data_ptr(uspi, ubh, i);
1103 ufs_trunc_branch(inode, NULL, 0, depth, ind); 1156 free_full_branch(inode, depth, ind);
1104 ubh_mark_buffer_dirty(ubh); 1157 ubh_mark_buffer_dirty(ubh);
1105 } 1158 }
1106 } else { 1159 } else {
@@ -1121,17 +1174,6 @@ static void ufs_trunc_branch(struct inode *inode, unsigned *offsets, int depth2,
1121 } 1174 }
1122 free_data(&ctx, 0, 0); 1175 free_data(&ctx, 0, 0);
1123 } 1176 }
1124 if (free_it) {
1125 tmp = ufs_data_ptr_to_cpu(sb, p);
1126 write_seqlock(&ufsi->meta_lock);
1127 ufs_data_ptr_clear(uspi, p);
1128 write_sequnlock(&ufsi->meta_lock);
1129
1130 ubh_bforget(ubh);
1131 ufs_free_blocks(inode, tmp, uspi->s_fpb);
1132 mark_inode_dirty(inode);
1133 return;
1134 }
1135 if (IS_SYNC(inode) && ubh_buffer_dirty(ubh)) 1177 if (IS_SYNC(inode) && ubh_buffer_dirty(ubh))
1136 ubh_sync_block(ubh); 1178 ubh_sync_block(ubh);
1137 ubh_brelse(ubh); 1179 ubh_brelse(ubh);
@@ -1235,7 +1277,7 @@ static void __ufs_truncate_blocks(struct inode *inode)
1235 ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]++)); 1277 ufs_get_direct_data_ptr(uspi, ufsi, offsets[0]++));
1236 } 1278 }
1237 for (i = offsets[0]; i <= UFS_TIND_BLOCK; i++) { 1279 for (i = offsets[0]; i <= UFS_TIND_BLOCK; i++) {
1238 ufs_trunc_branch(inode, NULL, 0, i - UFS_IND_BLOCK + 1, 1280 free_full_branch(inode, i - UFS_IND_BLOCK + 1,
1239 ufs_get_direct_data_ptr(uspi, ufsi, i)); 1281 ufs_get_direct_data_ptr(uspi, ufsi, i));
1240 } 1282 }
1241 ufsi->i_lastfrag = DIRECT_FRAGMENT; 1283 ufsi->i_lastfrag = DIRECT_FRAGMENT;