aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/move_extent.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/move_extent.c')
-rw-r--r--fs/ext4/move_extent.c149
1 files changed, 109 insertions, 40 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index e4bd8761498a..2258560e9722 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -128,6 +128,31 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
128} 128}
129 129
130/** 130/**
131 * mext_check_null_inode - NULL check for two inodes
132 *
133 * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
134 */
135static int
136mext_check_null_inode(struct inode *inode1, struct inode *inode2,
137 const char *function)
138{
139 int ret = 0;
140
141 if (inode1 == NULL) {
142 ext4_error(inode2->i_sb, function,
143 "Both inodes should not be NULL: "
144 "inode1 NULL inode2 %lu", inode2->i_ino);
145 ret = -EIO;
146 } else if (inode2 == NULL) {
147 ext4_error(inode1->i_sb, function,
148 "Both inodes should not be NULL: "
149 "inode1 %lu inode2 NULL", inode1->i_ino);
150 ret = -EIO;
151 }
152 return ret;
153}
154
155/**
131 * mext_double_down_read - Acquire two inodes' read semaphore 156 * mext_double_down_read - Acquire two inodes' read semaphore
132 * 157 *
133 * @orig_inode: original inode structure 158 * @orig_inode: original inode structure
@@ -139,8 +164,6 @@ mext_double_down_read(struct inode *orig_inode, struct inode *donor_inode)
139{ 164{
140 struct inode *first = orig_inode, *second = donor_inode; 165 struct inode *first = orig_inode, *second = donor_inode;
141 166
142 BUG_ON(orig_inode == NULL || donor_inode == NULL);
143
144 /* 167 /*
145 * Use the inode number to provide the stable locking order instead 168 * Use the inode number to provide the stable locking order instead
146 * of its address, because the C language doesn't guarantee you can 169 * of its address, because the C language doesn't guarantee you can
@@ -167,8 +190,6 @@ mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
167{ 190{
168 struct inode *first = orig_inode, *second = donor_inode; 191 struct inode *first = orig_inode, *second = donor_inode;
169 192
170 BUG_ON(orig_inode == NULL || donor_inode == NULL);
171
172 /* 193 /*
173 * Use the inode number to provide the stable locking order instead 194 * Use the inode number to provide the stable locking order instead
174 * of its address, because the C language doesn't guarantee you can 195 * of its address, because the C language doesn't guarantee you can
@@ -193,8 +214,6 @@ mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
193static void 214static void
194mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode) 215mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode)
195{ 216{
196 BUG_ON(orig_inode == NULL || donor_inode == NULL);
197
198 up_read(&EXT4_I(orig_inode)->i_data_sem); 217 up_read(&EXT4_I(orig_inode)->i_data_sem);
199 up_read(&EXT4_I(donor_inode)->i_data_sem); 218 up_read(&EXT4_I(donor_inode)->i_data_sem);
200} 219}
@@ -209,8 +228,6 @@ mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode)
209static void 228static void
210mext_double_up_write(struct inode *orig_inode, struct inode *donor_inode) 229mext_double_up_write(struct inode *orig_inode, struct inode *donor_inode)
211{ 230{
212 BUG_ON(orig_inode == NULL || donor_inode == NULL);
213
214 up_write(&EXT4_I(orig_inode)->i_data_sem); 231 up_write(&EXT4_I(orig_inode)->i_data_sem);
215 up_write(&EXT4_I(donor_inode)->i_data_sem); 232 up_write(&EXT4_I(donor_inode)->i_data_sem);
216} 233}
@@ -534,7 +551,15 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
534 * oext |-----------| 551 * oext |-----------|
535 * new_ext |-------| 552 * new_ext |-------|
536 */ 553 */
537 BUG_ON(le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end); 554 if (le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end) {
555 ext4_error(orig_inode->i_sb, __func__,
556 "new_ext_end(%u) should be less than or equal to "
557 "oext->ee_block(%u) + oext_alen(%d) - 1",
558 new_ext_end, le32_to_cpu(oext->ee_block),
559 oext_alen);
560 ret = -EIO;
561 goto out;
562 }
538 563
539 /* 564 /*
540 * Case: new_ext is smaller than original extent 565 * Case: new_ext is smaller than original extent
@@ -558,6 +583,7 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
558 583
559 ret = mext_insert_extents(handle, orig_inode, orig_path, o_start, 584 ret = mext_insert_extents(handle, orig_inode, orig_path, o_start,
560 o_end, &start_ext, &new_ext, &end_ext); 585 o_end, &start_ext, &new_ext, &end_ext);
586out:
561 return ret; 587 return ret;
562} 588}
563 589
@@ -668,7 +694,20 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
668 /* Loop for the donor extents */ 694 /* Loop for the donor extents */
669 while (1) { 695 while (1) {
670 /* The extent for donor must be found. */ 696 /* The extent for donor must be found. */
671 BUG_ON(!dext || donor_off != le32_to_cpu(tmp_dext.ee_block)); 697 if (!dext) {
698 ext4_error(donor_inode->i_sb, __func__,
699 "The extent for donor must be found");
700 err = -EIO;
701 goto out;
702 } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
703 ext4_error(donor_inode->i_sb, __func__,
704 "Donor offset(%u) and the first block of donor "
705 "extent(%u) should be equal",
706 donor_off,
707 le32_to_cpu(tmp_dext.ee_block));
708 err = -EIO;
709 goto out;
710 }
672 711
673 /* Set donor extent to orig extent */ 712 /* Set donor extent to orig extent */
674 err = mext_leaf_block(handle, orig_inode, 713 err = mext_leaf_block(handle, orig_inode,
@@ -1050,18 +1089,23 @@ mext_check_arguments(struct inode *orig_inode,
1050 * @inode1: the inode structure 1089 * @inode1: the inode structure
1051 * @inode2: the inode structure 1090 * @inode2: the inode structure
1052 * 1091 *
1053 * Lock two inodes' i_mutex by i_ino order. This function is moved from 1092 * Lock two inodes' i_mutex by i_ino order.
1054 * fs/inode.c. 1093 * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
1055 */ 1094 */
1056static void 1095static int
1057mext_inode_double_lock(struct inode *inode1, struct inode *inode2) 1096mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
1058{ 1097{
1059 if (inode1 == NULL || inode2 == NULL || inode1 == inode2) { 1098 int ret = 0;
1060 if (inode1) 1099
1061 mutex_lock(&inode1->i_mutex); 1100 BUG_ON(inode1 == NULL && inode2 == NULL);
1062 else if (inode2) 1101
1063 mutex_lock(&inode2->i_mutex); 1102 ret = mext_check_null_inode(inode1, inode2, __func__);
1064 return; 1103 if (ret < 0)
1104 goto out;
1105
1106 if (inode1 == inode2) {
1107 mutex_lock(&inode1->i_mutex);
1108 goto out;
1065 } 1109 }
1066 1110
1067 if (inode1->i_ino < inode2->i_ino) { 1111 if (inode1->i_ino < inode2->i_ino) {
@@ -1071,6 +1115,9 @@ mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
1071 mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT); 1115 mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
1072 mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD); 1116 mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
1073 } 1117 }
1118
1119out:
1120 return ret;
1074} 1121}
1075 1122
1076/** 1123/**
@@ -1079,17 +1126,28 @@ mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
1079 * @inode1: the inode that is released first 1126 * @inode1: the inode that is released first
1080 * @inode2: the inode that is released second 1127 * @inode2: the inode that is released second
1081 * 1128 *
1082 * This function is moved from fs/inode.c. 1129 * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
1083 */ 1130 */
1084 1131
1085static void 1132static int
1086mext_inode_double_unlock(struct inode *inode1, struct inode *inode2) 1133mext_inode_double_unlock(struct inode *inode1, struct inode *inode2)
1087{ 1134{
1135 int ret = 0;
1136
1137 BUG_ON(inode1 == NULL && inode2 == NULL);
1138
1139 ret = mext_check_null_inode(inode1, inode2, __func__);
1140 if (ret < 0)
1141 goto out;
1142
1088 if (inode1) 1143 if (inode1)
1089 mutex_unlock(&inode1->i_mutex); 1144 mutex_unlock(&inode1->i_mutex);
1090 1145
1091 if (inode2 && inode2 != inode1) 1146 if (inode2 && inode2 != inode1)
1092 mutex_unlock(&inode2->i_mutex); 1147 mutex_unlock(&inode2->i_mutex);
1148
1149out:
1150 return ret;
1093} 1151}
1094 1152
1095/** 1153/**
@@ -1146,21 +1204,23 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1146 ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0; 1204 ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
1147 ext4_lblk_t rest_blocks; 1205 ext4_lblk_t rest_blocks;
1148 pgoff_t orig_page_offset = 0, seq_end_page; 1206 pgoff_t orig_page_offset = 0, seq_end_page;
1149 int ret, depth, last_extent = 0; 1207 int ret1, ret2, depth, last_extent = 0;
1150 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; 1208 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
1151 int data_offset_in_page; 1209 int data_offset_in_page;
1152 int block_len_in_page; 1210 int block_len_in_page;
1153 int uninit; 1211 int uninit;
1154 1212
1155 /* protect orig and donor against a truncate */ 1213 /* protect orig and donor against a truncate */
1156 mext_inode_double_lock(orig_inode, donor_inode); 1214 ret1 = mext_inode_double_lock(orig_inode, donor_inode);
1215 if (ret1 < 0)
1216 return ret1;
1157 1217
1158 mext_double_down_read(orig_inode, donor_inode); 1218 mext_double_down_read(orig_inode, donor_inode);
1159 /* Check the filesystem environment whether move_extent can be done */ 1219 /* Check the filesystem environment whether move_extent can be done */
1160 ret = mext_check_arguments(orig_inode, donor_inode, orig_start, 1220 ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
1161 donor_start, &len, *moved_len); 1221 donor_start, &len, *moved_len);
1162 mext_double_up_read(orig_inode, donor_inode); 1222 mext_double_up_read(orig_inode, donor_inode);
1163 if (ret) 1223 if (ret1)
1164 goto out2; 1224 goto out2;
1165 1225
1166 file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits; 1226 file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
@@ -1168,19 +1228,19 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1168 if (file_end < block_end) 1228 if (file_end < block_end)
1169 len -= block_end - file_end; 1229 len -= block_end - file_end;
1170 1230
1171 ret = get_ext_path(orig_inode, block_start, &orig_path); 1231 ret1 = get_ext_path(orig_inode, block_start, &orig_path);
1172 if (orig_path == NULL) 1232 if (orig_path == NULL)
1173 goto out2; 1233 goto out2;
1174 1234
1175 /* Get path structure to check the hole */ 1235 /* Get path structure to check the hole */
1176 ret = get_ext_path(orig_inode, block_start, &holecheck_path); 1236 ret1 = get_ext_path(orig_inode, block_start, &holecheck_path);
1177 if (holecheck_path == NULL) 1237 if (holecheck_path == NULL)
1178 goto out; 1238 goto out;
1179 1239
1180 depth = ext_depth(orig_inode); 1240 depth = ext_depth(orig_inode);
1181 ext_cur = holecheck_path[depth].p_ext; 1241 ext_cur = holecheck_path[depth].p_ext;
1182 if (ext_cur == NULL) { 1242 if (ext_cur == NULL) {
1183 ret = -EINVAL; 1243 ret1 = -EINVAL;
1184 goto out; 1244 goto out;
1185 } 1245 }
1186 1246
@@ -1193,13 +1253,13 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1193 last_extent = mext_next_extent(orig_inode, 1253 last_extent = mext_next_extent(orig_inode,
1194 holecheck_path, &ext_cur); 1254 holecheck_path, &ext_cur);
1195 if (last_extent < 0) { 1255 if (last_extent < 0) {
1196 ret = last_extent; 1256 ret1 = last_extent;
1197 goto out; 1257 goto out;
1198 } 1258 }
1199 last_extent = mext_next_extent(orig_inode, orig_path, 1259 last_extent = mext_next_extent(orig_inode, orig_path,
1200 &ext_dummy); 1260 &ext_dummy);
1201 if (last_extent < 0) { 1261 if (last_extent < 0) {
1202 ret = last_extent; 1262 ret1 = last_extent;
1203 goto out; 1263 goto out;
1204 } 1264 }
1205 } 1265 }
@@ -1209,7 +1269,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1209 if (le32_to_cpu(ext_cur->ee_block) > block_end) { 1269 if (le32_to_cpu(ext_cur->ee_block) > block_end) {
1210 ext4_debug("ext4 move extent: The specified range of file " 1270 ext4_debug("ext4 move extent: The specified range of file "
1211 "may be the hole\n"); 1271 "may be the hole\n");
1212 ret = -EINVAL; 1272 ret1 = -EINVAL;
1213 goto out; 1273 goto out;
1214 } 1274 }
1215 1275
@@ -1229,7 +1289,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1229 last_extent = mext_next_extent(orig_inode, holecheck_path, 1289 last_extent = mext_next_extent(orig_inode, holecheck_path,
1230 &ext_cur); 1290 &ext_cur);
1231 if (last_extent < 0) { 1291 if (last_extent < 0) {
1232 ret = last_extent; 1292 ret1 = last_extent;
1233 break; 1293 break;
1234 } 1294 }
1235 add_blocks = ext4_ext_get_actual_len(ext_cur); 1295 add_blocks = ext4_ext_get_actual_len(ext_cur);
@@ -1281,16 +1341,23 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1281 while (orig_page_offset <= seq_end_page) { 1341 while (orig_page_offset <= seq_end_page) {
1282 1342
1283 /* Swap original branches with new branches */ 1343 /* Swap original branches with new branches */
1284 ret = move_extent_per_page(o_filp, donor_inode, 1344 ret1 = move_extent_per_page(o_filp, donor_inode,
1285 orig_page_offset, 1345 orig_page_offset,
1286 data_offset_in_page, 1346 data_offset_in_page,
1287 block_len_in_page, uninit); 1347 block_len_in_page, uninit);
1288 if (ret < 0) 1348 if (ret1 < 0)
1289 goto out; 1349 goto out;
1290 orig_page_offset++; 1350 orig_page_offset++;
1291 /* Count how many blocks we have exchanged */ 1351 /* Count how many blocks we have exchanged */
1292 *moved_len += block_len_in_page; 1352 *moved_len += block_len_in_page;
1293 BUG_ON(*moved_len > len); 1353 if (*moved_len > len) {
1354 ext4_error(orig_inode->i_sb, __func__,
1355 "We replaced blocks too much! "
1356 "sum of replaced: %llu requested: %llu",
1357 *moved_len, len);
1358 ret1 = -EIO;
1359 goto out;
1360 }
1294 1361
1295 data_offset_in_page = 0; 1362 data_offset_in_page = 0;
1296 rest_blocks -= block_len_in_page; 1363 rest_blocks -= block_len_in_page;
@@ -1303,7 +1370,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1303 /* Decrease buffer counter */ 1370 /* Decrease buffer counter */
1304 if (holecheck_path) 1371 if (holecheck_path)
1305 ext4_ext_drop_refs(holecheck_path); 1372 ext4_ext_drop_refs(holecheck_path);
1306 ret = get_ext_path(orig_inode, seq_start, &holecheck_path); 1373 ret1 = get_ext_path(orig_inode, seq_start, &holecheck_path);
1307 if (holecheck_path == NULL) 1374 if (holecheck_path == NULL)
1308 break; 1375 break;
1309 depth = holecheck_path->p_depth; 1376 depth = holecheck_path->p_depth;
@@ -1311,7 +1378,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1311 /* Decrease buffer counter */ 1378 /* Decrease buffer counter */
1312 if (orig_path) 1379 if (orig_path)
1313 ext4_ext_drop_refs(orig_path); 1380 ext4_ext_drop_refs(orig_path);
1314 ret = get_ext_path(orig_inode, seq_start, &orig_path); 1381 ret1 = get_ext_path(orig_inode, seq_start, &orig_path);
1315 if (orig_path == NULL) 1382 if (orig_path == NULL)
1316 break; 1383 break;
1317 1384
@@ -1330,10 +1397,12 @@ out:
1330 kfree(holecheck_path); 1397 kfree(holecheck_path);
1331 } 1398 }
1332out2: 1399out2:
1333 mext_inode_double_unlock(orig_inode, donor_inode); 1400 ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
1334 1401
1335 if (ret) 1402 if (ret1)
1336 return ret; 1403 return ret1;
1404 else if (ret2)
1405 return ret2;
1337 1406
1338 return 0; 1407 return 0;
1339} 1408}