diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-09-05 16:13:11 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:07 -0400 |
commit | e02119d5a7b4396c5a872582fddc8bd6d305a70a (patch) | |
tree | 825efe2a79dbca8d61256183f3526a5b5dc40dc6 /fs/btrfs/inode.c | |
parent | a1b32a5932cfac7c38b442582285f3da2a09dfd8 (diff) |
Btrfs: Add a write ahead tree log to optimize synchronous operations
File syncs and directory syncs are optimized by copying their
items into a special (copy-on-write) log tree. There is one log tree per
subvolume and the btrfs super block points to a tree of log tree roots.
After a crash, items are copied out of the log tree and back into the
subvolume. See tree-log.c for all the details.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 261 |
1 files changed, 134 insertions, 127 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 43d3f2649ca3..65df9d830230 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include "volumes.h" | 46 | #include "volumes.h" |
47 | #include "ordered-data.h" | 47 | #include "ordered-data.h" |
48 | #include "xattr.h" | 48 | #include "xattr.h" |
49 | #include "compat.h" | ||
50 | #include "tree-log.h" | ||
49 | 51 | ||
50 | struct btrfs_iget_args { | 52 | struct btrfs_iget_args { |
51 | u64 ino; | 53 | u64 ino; |
@@ -586,6 +588,7 @@ nocow: | |||
586 | &ordered_extent->list); | 588 | &ordered_extent->list); |
587 | 589 | ||
588 | btrfs_ordered_update_i_size(inode, ordered_extent); | 590 | btrfs_ordered_update_i_size(inode, ordered_extent); |
591 | btrfs_update_inode(trans, root, inode); | ||
589 | btrfs_remove_ordered_extent(inode, ordered_extent); | 592 | btrfs_remove_ordered_extent(inode, ordered_extent); |
590 | 593 | ||
591 | /* once for us */ | 594 | /* once for us */ |
@@ -593,7 +596,6 @@ nocow: | |||
593 | /* once for the tree */ | 596 | /* once for the tree */ |
594 | btrfs_put_ordered_extent(ordered_extent); | 597 | btrfs_put_ordered_extent(ordered_extent); |
595 | 598 | ||
596 | btrfs_update_inode(trans, root, inode); | ||
597 | btrfs_end_transaction(trans, root); | 599 | btrfs_end_transaction(trans, root); |
598 | return 0; | 600 | return 0; |
599 | } | 601 | } |
@@ -1007,7 +1009,8 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
1007 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(leaf, tspec); | 1009 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(leaf, tspec); |
1008 | 1010 | ||
1009 | inode->i_blocks = btrfs_inode_nblocks(leaf, inode_item); | 1011 | inode->i_blocks = btrfs_inode_nblocks(leaf, inode_item); |
1010 | inode->i_generation = btrfs_inode_generation(leaf, inode_item); | 1012 | BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item); |
1013 | inode->i_generation = BTRFS_I(inode)->generation; | ||
1011 | inode->i_rdev = 0; | 1014 | inode->i_rdev = 0; |
1012 | rdev = btrfs_inode_rdev(leaf, inode_item); | 1015 | rdev = btrfs_inode_rdev(leaf, inode_item); |
1013 | 1016 | ||
@@ -1056,7 +1059,8 @@ make_bad: | |||
1056 | make_bad_inode(inode); | 1059 | make_bad_inode(inode); |
1057 | } | 1060 | } |
1058 | 1061 | ||
1059 | static void fill_inode_item(struct extent_buffer *leaf, | 1062 | static void fill_inode_item(struct btrfs_trans_handle *trans, |
1063 | struct extent_buffer *leaf, | ||
1060 | struct btrfs_inode_item *item, | 1064 | struct btrfs_inode_item *item, |
1061 | struct inode *inode) | 1065 | struct inode *inode) |
1062 | { | 1066 | { |
@@ -1082,7 +1086,8 @@ static void fill_inode_item(struct extent_buffer *leaf, | |||
1082 | inode->i_ctime.tv_nsec); | 1086 | inode->i_ctime.tv_nsec); |
1083 | 1087 | ||
1084 | btrfs_set_inode_nblocks(leaf, item, inode->i_blocks); | 1088 | btrfs_set_inode_nblocks(leaf, item, inode->i_blocks); |
1085 | btrfs_set_inode_generation(leaf, item, inode->i_generation); | 1089 | btrfs_set_inode_generation(leaf, item, BTRFS_I(inode)->generation); |
1090 | btrfs_set_inode_transid(leaf, item, trans->transid); | ||
1086 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); | 1091 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); |
1087 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); | 1092 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); |
1088 | btrfs_set_inode_block_group(leaf, item, | 1093 | btrfs_set_inode_block_group(leaf, item, |
@@ -1112,7 +1117,7 @@ int noinline btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
1112 | inode_item = btrfs_item_ptr(leaf, path->slots[0], | 1117 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
1113 | struct btrfs_inode_item); | 1118 | struct btrfs_inode_item); |
1114 | 1119 | ||
1115 | fill_inode_item(leaf, inode_item, inode); | 1120 | fill_inode_item(trans, leaf, inode_item, inode); |
1116 | btrfs_mark_buffer_dirty(leaf); | 1121 | btrfs_mark_buffer_dirty(leaf); |
1117 | btrfs_set_inode_last_trans(trans, inode); | 1122 | btrfs_set_inode_last_trans(trans, inode); |
1118 | ret = 0; | 1123 | ret = 0; |
@@ -1122,14 +1127,12 @@ failed: | |||
1122 | } | 1127 | } |
1123 | 1128 | ||
1124 | 1129 | ||
1125 | static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | 1130 | int btrfs_unlink_inode(struct btrfs_trans_handle *trans, |
1126 | struct btrfs_root *root, | 1131 | struct btrfs_root *root, |
1127 | struct inode *dir, | 1132 | struct inode *dir, struct inode *inode, |
1128 | struct dentry *dentry) | 1133 | const char *name, int name_len) |
1129 | { | 1134 | { |
1130 | struct btrfs_path *path; | 1135 | struct btrfs_path *path; |
1131 | const char *name = dentry->d_name.name; | ||
1132 | int name_len = dentry->d_name.len; | ||
1133 | int ret = 0; | 1136 | int ret = 0; |
1134 | struct extent_buffer *leaf; | 1137 | struct extent_buffer *leaf; |
1135 | struct btrfs_dir_item *di; | 1138 | struct btrfs_dir_item *di; |
@@ -1160,13 +1163,12 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
1160 | btrfs_release_path(root, path); | 1163 | btrfs_release_path(root, path); |
1161 | 1164 | ||
1162 | ret = btrfs_del_inode_ref(trans, root, name, name_len, | 1165 | ret = btrfs_del_inode_ref(trans, root, name, name_len, |
1163 | dentry->d_inode->i_ino, | 1166 | inode->i_ino, |
1164 | dentry->d_parent->d_inode->i_ino, &index); | 1167 | dir->i_ino, &index); |
1165 | if (ret) { | 1168 | if (ret) { |
1166 | printk("failed to delete reference to %.*s, " | 1169 | printk("failed to delete reference to %.*s, " |
1167 | "inode %lu parent %lu\n", name_len, name, | 1170 | "inode %lu parent %lu\n", name_len, name, |
1168 | dentry->d_inode->i_ino, | 1171 | inode->i_ino, dir->i_ino); |
1169 | dentry->d_parent->d_inode->i_ino); | ||
1170 | goto err; | 1172 | goto err; |
1171 | } | 1173 | } |
1172 | 1174 | ||
@@ -1183,21 +1185,25 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, | |||
1183 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | 1185 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
1184 | btrfs_release_path(root, path); | 1186 | btrfs_release_path(root, path); |
1185 | 1187 | ||
1186 | dentry->d_inode->i_ctime = dir->i_ctime; | 1188 | ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len, |
1189 | inode, dir->i_ino); | ||
1190 | BUG_ON(ret); | ||
1191 | |||
1192 | ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len, | ||
1193 | dir, index); | ||
1194 | BUG_ON(ret); | ||
1187 | err: | 1195 | err: |
1188 | btrfs_free_path(path); | 1196 | btrfs_free_path(path); |
1189 | if (!ret) { | 1197 | if (ret) |
1190 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); | 1198 | goto out; |
1191 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | 1199 | |
1192 | btrfs_update_inode(trans, root, dir); | 1200 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); |
1193 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | 1201 | inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
1194 | dentry->d_inode->i_nlink--; | 1202 | btrfs_update_inode(trans, root, dir); |
1195 | #else | 1203 | btrfs_drop_nlink(inode); |
1196 | drop_nlink(dentry->d_inode); | 1204 | ret = btrfs_update_inode(trans, root, inode); |
1197 | #endif | 1205 | dir->i_sb->s_dirt = 1; |
1198 | ret = btrfs_update_inode(trans, root, dentry->d_inode); | 1206 | out: |
1199 | dir->i_sb->s_dirt = 1; | ||
1200 | } | ||
1201 | return ret; | 1207 | return ret; |
1202 | } | 1208 | } |
1203 | 1209 | ||
@@ -1218,7 +1224,8 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1218 | trans = btrfs_start_transaction(root, 1); | 1224 | trans = btrfs_start_transaction(root, 1); |
1219 | 1225 | ||
1220 | btrfs_set_trans_block_group(trans, dir); | 1226 | btrfs_set_trans_block_group(trans, dir); |
1221 | ret = btrfs_unlink_trans(trans, root, dir, dentry); | 1227 | ret = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, |
1228 | dentry->d_name.name, dentry->d_name.len); | ||
1222 | 1229 | ||
1223 | if (inode->i_nlink == 0) | 1230 | if (inode->i_nlink == 0) |
1224 | ret = btrfs_orphan_add(trans, inode); | 1231 | ret = btrfs_orphan_add(trans, inode); |
@@ -1256,7 +1263,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1256 | goto fail_trans; | 1263 | goto fail_trans; |
1257 | 1264 | ||
1258 | /* now the directory is empty */ | 1265 | /* now the directory is empty */ |
1259 | err = btrfs_unlink_trans(trans, root, dir, dentry); | 1266 | err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, |
1267 | dentry->d_name.name, dentry->d_name.len); | ||
1260 | if (!err) { | 1268 | if (!err) { |
1261 | btrfs_i_size_write(inode, 0); | 1269 | btrfs_i_size_write(inode, 0); |
1262 | } | 1270 | } |
@@ -1283,10 +1291,10 @@ fail: | |||
1283 | * min_type is the minimum key type to truncate down to. If set to 0, this | 1291 | * min_type is the minimum key type to truncate down to. If set to 0, this |
1284 | * will kill all the items on this inode, including the INODE_ITEM_KEY. | 1292 | * will kill all the items on this inode, including the INODE_ITEM_KEY. |
1285 | */ | 1293 | */ |
1286 | static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | 1294 | noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, |
1287 | struct btrfs_root *root, | 1295 | struct btrfs_root *root, |
1288 | struct inode *inode, | 1296 | struct inode *inode, |
1289 | u32 min_type) | 1297 | u64 new_size, u32 min_type) |
1290 | { | 1298 | { |
1291 | int ret; | 1299 | int ret; |
1292 | struct btrfs_path *path; | 1300 | struct btrfs_path *path; |
@@ -1307,7 +1315,9 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, | |||
1307 | int extent_type = -1; | 1315 | int extent_type = -1; |
1308 | u64 mask = root->sectorsize - 1; | 1316 | u64 mask = root->sectorsize - 1; |
1309 | 1317 | ||
1310 | btrfs_drop_extent_cache(inode, inode->i_size & (~mask), (u64)-1); | 1318 | if (root->ref_cows) |
1319 | btrfs_drop_extent_cache(inode, | ||
1320 | new_size & (~mask), (u64)-1); | ||
1311 | path = btrfs_alloc_path(); | 1321 | path = btrfs_alloc_path(); |
1312 | path->reada = -1; | 1322 | path->reada = -1; |
1313 | BUG_ON(!path); | 1323 | BUG_ON(!path); |
@@ -1324,7 +1334,13 @@ search_again: | |||
1324 | goto error; | 1334 | goto error; |
1325 | } | 1335 | } |
1326 | if (ret > 0) { | 1336 | if (ret > 0) { |
1327 | BUG_ON(path->slots[0] == 0); | 1337 | /* there are no items in the tree for us to truncate, we're |
1338 | * done | ||
1339 | */ | ||
1340 | if (path->slots[0] == 0) { | ||
1341 | ret = 0; | ||
1342 | goto error; | ||
1343 | } | ||
1328 | path->slots[0]--; | 1344 | path->slots[0]--; |
1329 | } | 1345 | } |
1330 | 1346 | ||
@@ -1358,10 +1374,10 @@ search_again: | |||
1358 | } | 1374 | } |
1359 | if (found_type == BTRFS_CSUM_ITEM_KEY) { | 1375 | if (found_type == BTRFS_CSUM_ITEM_KEY) { |
1360 | ret = btrfs_csum_truncate(trans, root, path, | 1376 | ret = btrfs_csum_truncate(trans, root, path, |
1361 | inode->i_size); | 1377 | new_size); |
1362 | BUG_ON(ret); | 1378 | BUG_ON(ret); |
1363 | } | 1379 | } |
1364 | if (item_end < inode->i_size) { | 1380 | if (item_end < new_size) { |
1365 | if (found_type == BTRFS_DIR_ITEM_KEY) { | 1381 | if (found_type == BTRFS_DIR_ITEM_KEY) { |
1366 | found_type = BTRFS_INODE_ITEM_KEY; | 1382 | found_type = BTRFS_INODE_ITEM_KEY; |
1367 | } else if (found_type == BTRFS_EXTENT_ITEM_KEY) { | 1383 | } else if (found_type == BTRFS_EXTENT_ITEM_KEY) { |
@@ -1378,7 +1394,7 @@ search_again: | |||
1378 | btrfs_set_key_type(&key, found_type); | 1394 | btrfs_set_key_type(&key, found_type); |
1379 | goto next; | 1395 | goto next; |
1380 | } | 1396 | } |
1381 | if (found_key.offset >= inode->i_size) | 1397 | if (found_key.offset >= new_size) |
1382 | del_item = 1; | 1398 | del_item = 1; |
1383 | else | 1399 | else |
1384 | del_item = 0; | 1400 | del_item = 0; |
@@ -1394,7 +1410,7 @@ search_again: | |||
1394 | if (!del_item) { | 1410 | if (!del_item) { |
1395 | u64 orig_num_bytes = | 1411 | u64 orig_num_bytes = |
1396 | btrfs_file_extent_num_bytes(leaf, fi); | 1412 | btrfs_file_extent_num_bytes(leaf, fi); |
1397 | extent_num_bytes = inode->i_size - | 1413 | extent_num_bytes = new_size - |
1398 | found_key.offset + root->sectorsize - 1; | 1414 | found_key.offset + root->sectorsize - 1; |
1399 | extent_num_bytes = extent_num_bytes & | 1415 | extent_num_bytes = extent_num_bytes & |
1400 | ~((u64)root->sectorsize - 1); | 1416 | ~((u64)root->sectorsize - 1); |
@@ -1402,7 +1418,7 @@ search_again: | |||
1402 | extent_num_bytes); | 1418 | extent_num_bytes); |
1403 | num_dec = (orig_num_bytes - | 1419 | num_dec = (orig_num_bytes - |
1404 | extent_num_bytes); | 1420 | extent_num_bytes); |
1405 | if (extent_start != 0) | 1421 | if (root->ref_cows && extent_start != 0) |
1406 | dec_i_blocks(inode, num_dec); | 1422 | dec_i_blocks(inode, num_dec); |
1407 | btrfs_mark_buffer_dirty(leaf); | 1423 | btrfs_mark_buffer_dirty(leaf); |
1408 | } else { | 1424 | } else { |
@@ -1413,22 +1429,29 @@ search_again: | |||
1413 | num_dec = btrfs_file_extent_num_bytes(leaf, fi); | 1429 | num_dec = btrfs_file_extent_num_bytes(leaf, fi); |
1414 | if (extent_start != 0) { | 1430 | if (extent_start != 0) { |
1415 | found_extent = 1; | 1431 | found_extent = 1; |
1416 | dec_i_blocks(inode, num_dec); | 1432 | if (root->ref_cows) |
1433 | dec_i_blocks(inode, num_dec); | ||
1434 | } | ||
1435 | if (root->ref_cows) { | ||
1436 | root_gen = | ||
1437 | btrfs_header_generation(leaf); | ||
1417 | } | 1438 | } |
1418 | root_gen = btrfs_header_generation(leaf); | ||
1419 | root_owner = btrfs_header_owner(leaf); | 1439 | root_owner = btrfs_header_owner(leaf); |
1420 | } | 1440 | } |
1421 | } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { | 1441 | } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { |
1422 | if (!del_item) { | 1442 | if (!del_item) { |
1423 | u32 newsize = inode->i_size - found_key.offset; | 1443 | u32 size = new_size - found_key.offset; |
1424 | dec_i_blocks(inode, item_end + 1 - | 1444 | |
1425 | found_key.offset - newsize); | 1445 | if (root->ref_cows) { |
1426 | newsize = | 1446 | dec_i_blocks(inode, item_end + 1 - |
1427 | btrfs_file_extent_calc_inline_size(newsize); | 1447 | found_key.offset - size); |
1448 | } | ||
1449 | size = | ||
1450 | btrfs_file_extent_calc_inline_size(size); | ||
1428 | ret = btrfs_truncate_item(trans, root, path, | 1451 | ret = btrfs_truncate_item(trans, root, path, |
1429 | newsize, 1); | 1452 | size, 1); |
1430 | BUG_ON(ret); | 1453 | BUG_ON(ret); |
1431 | } else { | 1454 | } else if (root->ref_cows) { |
1432 | dec_i_blocks(inode, item_end + 1 - | 1455 | dec_i_blocks(inode, item_end + 1 - |
1433 | found_key.offset); | 1456 | found_key.offset); |
1434 | } | 1457 | } |
@@ -1666,7 +1689,7 @@ void btrfs_delete_inode(struct inode *inode) | |||
1666 | trans = btrfs_start_transaction(root, 1); | 1689 | trans = btrfs_start_transaction(root, 1); |
1667 | 1690 | ||
1668 | btrfs_set_trans_block_group(trans, inode); | 1691 | btrfs_set_trans_block_group(trans, inode); |
1669 | ret = btrfs_truncate_in_trans(trans, root, inode, 0); | 1692 | ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, 0); |
1670 | if (ret) { | 1693 | if (ret) { |
1671 | btrfs_orphan_del(NULL, inode); | 1694 | btrfs_orphan_del(NULL, inode); |
1672 | goto no_delete_lock; | 1695 | goto no_delete_lock; |
@@ -1753,15 +1776,20 @@ static int fixup_tree_root_location(struct btrfs_root *root, | |||
1753 | return 0; | 1776 | return 0; |
1754 | } | 1777 | } |
1755 | 1778 | ||
1756 | static int btrfs_init_locked_inode(struct inode *inode, void *p) | 1779 | static noinline void init_btrfs_i(struct inode *inode) |
1757 | { | 1780 | { |
1758 | struct btrfs_iget_args *args = p; | 1781 | struct btrfs_inode *bi = BTRFS_I(inode); |
1759 | inode->i_ino = args->ino; | 1782 | |
1760 | BTRFS_I(inode)->root = args->root; | 1783 | bi->i_acl = NULL; |
1761 | BTRFS_I(inode)->delalloc_bytes = 0; | 1784 | bi->i_default_acl = NULL; |
1762 | inode->i_mapping->writeback_index = 0; | 1785 | |
1763 | BTRFS_I(inode)->disk_i_size = 0; | 1786 | bi->generation = 0; |
1764 | BTRFS_I(inode)->index_cnt = (u64)-1; | 1787 | bi->last_trans = 0; |
1788 | bi->logged_trans = 0; | ||
1789 | bi->delalloc_bytes = 0; | ||
1790 | bi->disk_i_size = 0; | ||
1791 | bi->flags = 0; | ||
1792 | bi->index_cnt = (u64)-1; | ||
1765 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); | 1793 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); |
1766 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | 1794 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, |
1767 | inode->i_mapping, GFP_NOFS); | 1795 | inode->i_mapping, GFP_NOFS); |
@@ -1771,6 +1799,15 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
1771 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | 1799 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); |
1772 | mutex_init(&BTRFS_I(inode)->csum_mutex); | 1800 | mutex_init(&BTRFS_I(inode)->csum_mutex); |
1773 | mutex_init(&BTRFS_I(inode)->extent_mutex); | 1801 | mutex_init(&BTRFS_I(inode)->extent_mutex); |
1802 | mutex_init(&BTRFS_I(inode)->log_mutex); | ||
1803 | } | ||
1804 | |||
1805 | static int btrfs_init_locked_inode(struct inode *inode, void *p) | ||
1806 | { | ||
1807 | struct btrfs_iget_args *args = p; | ||
1808 | inode->i_ino = args->ino; | ||
1809 | init_btrfs_i(inode); | ||
1810 | BTRFS_I(inode)->root = args->root; | ||
1774 | return 0; | 1811 | return 0; |
1775 | } | 1812 | } |
1776 | 1813 | ||
@@ -2263,21 +2300,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
2263 | * btrfs_get_inode_index_count has an explanation for the magic | 2300 | * btrfs_get_inode_index_count has an explanation for the magic |
2264 | * number | 2301 | * number |
2265 | */ | 2302 | */ |
2303 | init_btrfs_i(inode); | ||
2266 | BTRFS_I(inode)->index_cnt = 2; | 2304 | BTRFS_I(inode)->index_cnt = 2; |
2267 | |||
2268 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); | ||
2269 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
2270 | inode->i_mapping, GFP_NOFS); | ||
2271 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | ||
2272 | inode->i_mapping, GFP_NOFS); | ||
2273 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | ||
2274 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
2275 | mutex_init(&BTRFS_I(inode)->csum_mutex); | ||
2276 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
2277 | BTRFS_I(inode)->delalloc_bytes = 0; | ||
2278 | inode->i_mapping->writeback_index = 0; | ||
2279 | BTRFS_I(inode)->disk_i_size = 0; | ||
2280 | BTRFS_I(inode)->root = root; | 2305 | BTRFS_I(inode)->root = root; |
2306 | BTRFS_I(inode)->generation = trans->transid; | ||
2281 | 2307 | ||
2282 | if (mode & S_IFDIR) | 2308 | if (mode & S_IFDIR) |
2283 | owner = 0; | 2309 | owner = 0; |
@@ -2290,7 +2316,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
2290 | new_inode_group = group; | 2316 | new_inode_group = group; |
2291 | } | 2317 | } |
2292 | BTRFS_I(inode)->block_group = new_inode_group; | 2318 | BTRFS_I(inode)->block_group = new_inode_group; |
2293 | BTRFS_I(inode)->flags = 0; | ||
2294 | 2319 | ||
2295 | key[0].objectid = objectid; | 2320 | key[0].objectid = objectid; |
2296 | btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); | 2321 | btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); |
@@ -2318,7 +2343,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
2318 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 2343 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
2319 | inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], | 2344 | inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], |
2320 | struct btrfs_inode_item); | 2345 | struct btrfs_inode_item); |
2321 | fill_inode_item(path->nodes[0], inode_item, inode); | 2346 | fill_inode_item(trans, path->nodes[0], inode_item, inode); |
2322 | 2347 | ||
2323 | ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1, | 2348 | ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1, |
2324 | struct btrfs_inode_ref); | 2349 | struct btrfs_inode_ref); |
@@ -2349,38 +2374,34 @@ static inline u8 btrfs_inode_type(struct inode *inode) | |||
2349 | return btrfs_type_by_mode[(inode->i_mode & S_IFMT) >> S_SHIFT]; | 2374 | return btrfs_type_by_mode[(inode->i_mode & S_IFMT) >> S_SHIFT]; |
2350 | } | 2375 | } |
2351 | 2376 | ||
2352 | static int btrfs_add_link(struct btrfs_trans_handle *trans, | 2377 | int btrfs_add_link(struct btrfs_trans_handle *trans, |
2353 | struct dentry *dentry, struct inode *inode, | 2378 | struct inode *parent_inode, struct inode *inode, |
2354 | int add_backref, u64 index) | 2379 | const char *name, int name_len, int add_backref, u64 index) |
2355 | { | 2380 | { |
2356 | int ret; | 2381 | int ret; |
2357 | struct btrfs_key key; | 2382 | struct btrfs_key key; |
2358 | struct btrfs_root *root = BTRFS_I(dentry->d_parent->d_inode)->root; | 2383 | struct btrfs_root *root = BTRFS_I(parent_inode)->root; |
2359 | struct inode *parent_inode = dentry->d_parent->d_inode; | ||
2360 | 2384 | ||
2361 | key.objectid = inode->i_ino; | 2385 | key.objectid = inode->i_ino; |
2362 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 2386 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
2363 | key.offset = 0; | 2387 | key.offset = 0; |
2364 | 2388 | ||
2365 | ret = btrfs_insert_dir_item(trans, root, | 2389 | ret = btrfs_insert_dir_item(trans, root, name, name_len, |
2366 | dentry->d_name.name, dentry->d_name.len, | 2390 | parent_inode->i_ino, |
2367 | dentry->d_parent->d_inode->i_ino, | ||
2368 | &key, btrfs_inode_type(inode), | 2391 | &key, btrfs_inode_type(inode), |
2369 | index); | 2392 | index); |
2370 | if (ret == 0) { | 2393 | if (ret == 0) { |
2371 | if (add_backref) { | 2394 | if (add_backref) { |
2372 | ret = btrfs_insert_inode_ref(trans, root, | 2395 | ret = btrfs_insert_inode_ref(trans, root, |
2373 | dentry->d_name.name, | 2396 | name, name_len, |
2374 | dentry->d_name.len, | 2397 | inode->i_ino, |
2375 | inode->i_ino, | 2398 | parent_inode->i_ino, |
2376 | parent_inode->i_ino, | 2399 | index); |
2377 | index); | ||
2378 | } | 2400 | } |
2379 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 2401 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
2380 | dentry->d_name.len * 2); | 2402 | name_len * 2); |
2381 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; | 2403 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; |
2382 | ret = btrfs_update_inode(trans, root, | 2404 | ret = btrfs_update_inode(trans, root, parent_inode); |
2383 | dentry->d_parent->d_inode); | ||
2384 | } | 2405 | } |
2385 | return ret; | 2406 | return ret; |
2386 | } | 2407 | } |
@@ -2389,7 +2410,9 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans, | |||
2389 | struct dentry *dentry, struct inode *inode, | 2410 | struct dentry *dentry, struct inode *inode, |
2390 | int backref, u64 index) | 2411 | int backref, u64 index) |
2391 | { | 2412 | { |
2392 | int err = btrfs_add_link(trans, dentry, inode, backref, index); | 2413 | int err = btrfs_add_link(trans, dentry->d_parent->d_inode, |
2414 | inode, dentry->d_name.name, | ||
2415 | dentry->d_name.len, backref, index); | ||
2393 | if (!err) { | 2416 | if (!err) { |
2394 | d_instantiate(dentry, inode); | 2417 | d_instantiate(dentry, inode); |
2395 | return 0; | 2418 | return 0; |
@@ -2513,19 +2536,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
2513 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | 2536 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; |
2514 | inode->i_fop = &btrfs_file_operations; | 2537 | inode->i_fop = &btrfs_file_operations; |
2515 | inode->i_op = &btrfs_file_inode_operations; | 2538 | inode->i_op = &btrfs_file_inode_operations; |
2516 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); | ||
2517 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
2518 | inode->i_mapping, GFP_NOFS); | ||
2519 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | ||
2520 | inode->i_mapping, GFP_NOFS); | ||
2521 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
2522 | mutex_init(&BTRFS_I(inode)->csum_mutex); | ||
2523 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
2524 | BTRFS_I(inode)->delalloc_bytes = 0; | ||
2525 | BTRFS_I(inode)->disk_i_size = 0; | ||
2526 | inode->i_mapping->writeback_index = 0; | ||
2527 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 2539 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
2528 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | ||
2529 | } | 2540 | } |
2530 | dir->i_sb->s_dirt = 1; | 2541 | dir->i_sb->s_dirt = 1; |
2531 | btrfs_update_inode_block_group(trans, inode); | 2542 | btrfs_update_inode_block_group(trans, inode); |
@@ -2556,11 +2567,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
2556 | if (inode->i_nlink == 0) | 2567 | if (inode->i_nlink == 0) |
2557 | return -ENOENT; | 2568 | return -ENOENT; |
2558 | 2569 | ||
2559 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | 2570 | btrfs_inc_nlink(inode); |
2560 | inode->i_nlink++; | ||
2561 | #else | ||
2562 | inc_nlink(inode); | ||
2563 | #endif | ||
2564 | err = btrfs_check_free_space(root, 1, 0); | 2571 | err = btrfs_check_free_space(root, 1, 0); |
2565 | if (err) | 2572 | if (err) |
2566 | goto fail; | 2573 | goto fail; |
@@ -2650,7 +2657,9 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
2650 | if (err) | 2657 | if (err) |
2651 | goto out_fail; | 2658 | goto out_fail; |
2652 | 2659 | ||
2653 | err = btrfs_add_link(trans, dentry, inode, 0, index); | 2660 | err = btrfs_add_link(trans, dentry->d_parent->d_inode, |
2661 | inode, dentry->d_name.name, | ||
2662 | dentry->d_name.len, 0, index); | ||
2654 | if (err) | 2663 | if (err) |
2655 | goto out_fail; | 2664 | goto out_fail; |
2656 | 2665 | ||
@@ -3221,7 +3230,7 @@ static void btrfs_truncate(struct inode *inode) | |||
3221 | if (ret) | 3230 | if (ret) |
3222 | goto out; | 3231 | goto out; |
3223 | /* FIXME, add redo link to tree so we don't leak on crash */ | 3232 | /* FIXME, add redo link to tree so we don't leak on crash */ |
3224 | ret = btrfs_truncate_in_trans(trans, root, inode, | 3233 | ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, |
3225 | BTRFS_EXTENT_DATA_KEY); | 3234 | BTRFS_EXTENT_DATA_KEY); |
3226 | btrfs_update_inode(trans, root, inode); | 3235 | btrfs_update_inode(trans, root, inode); |
3227 | 3236 | ||
@@ -3304,6 +3313,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
3304 | if (!ei) | 3313 | if (!ei) |
3305 | return NULL; | 3314 | return NULL; |
3306 | ei->last_trans = 0; | 3315 | ei->last_trans = 0; |
3316 | ei->logged_trans = 0; | ||
3307 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); | 3317 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); |
3308 | ei->i_acl = BTRFS_ACL_NOT_CACHED; | 3318 | ei->i_acl = BTRFS_ACL_NOT_CACHED; |
3309 | ei->i_default_acl = BTRFS_ACL_NOT_CACHED; | 3319 | ei->i_default_acl = BTRFS_ACL_NOT_CACHED; |
@@ -3463,31 +3473,39 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
3463 | 3473 | ||
3464 | btrfs_set_trans_block_group(trans, new_dir); | 3474 | btrfs_set_trans_block_group(trans, new_dir); |
3465 | 3475 | ||
3466 | old_dentry->d_inode->i_nlink++; | 3476 | btrfs_inc_nlink(old_dentry->d_inode); |
3467 | old_dir->i_ctime = old_dir->i_mtime = ctime; | 3477 | old_dir->i_ctime = old_dir->i_mtime = ctime; |
3468 | new_dir->i_ctime = new_dir->i_mtime = ctime; | 3478 | new_dir->i_ctime = new_dir->i_mtime = ctime; |
3469 | old_inode->i_ctime = ctime; | 3479 | old_inode->i_ctime = ctime; |
3470 | 3480 | ||
3471 | ret = btrfs_unlink_trans(trans, root, old_dir, old_dentry); | 3481 | ret = btrfs_unlink_inode(trans, root, old_dir, old_dentry->d_inode, |
3482 | old_dentry->d_name.name, | ||
3483 | old_dentry->d_name.len); | ||
3472 | if (ret) | 3484 | if (ret) |
3473 | goto out_fail; | 3485 | goto out_fail; |
3474 | 3486 | ||
3475 | if (new_inode) { | 3487 | if (new_inode) { |
3476 | new_inode->i_ctime = CURRENT_TIME; | 3488 | new_inode->i_ctime = CURRENT_TIME; |
3477 | ret = btrfs_unlink_trans(trans, root, new_dir, new_dentry); | 3489 | ret = btrfs_unlink_inode(trans, root, new_dir, |
3490 | new_dentry->d_inode, | ||
3491 | new_dentry->d_name.name, | ||
3492 | new_dentry->d_name.len); | ||
3478 | if (ret) | 3493 | if (ret) |
3479 | goto out_fail; | 3494 | goto out_fail; |
3480 | if (new_inode->i_nlink == 0) { | 3495 | if (new_inode->i_nlink == 0) { |
3481 | ret = btrfs_orphan_add(trans, new_inode); | 3496 | ret = btrfs_orphan_add(trans, new_dentry->d_inode); |
3482 | if (ret) | 3497 | if (ret) |
3483 | goto out_fail; | 3498 | goto out_fail; |
3484 | } | 3499 | } |
3500 | |||
3485 | } | 3501 | } |
3486 | ret = btrfs_set_inode_index(new_dir, old_inode, &index); | 3502 | ret = btrfs_set_inode_index(new_dir, old_inode, &index); |
3487 | if (ret) | 3503 | if (ret) |
3488 | goto out_fail; | 3504 | goto out_fail; |
3489 | 3505 | ||
3490 | ret = btrfs_add_link(trans, new_dentry, old_inode, 1, index); | 3506 | ret = btrfs_add_link(trans, new_dentry->d_parent->d_inode, |
3507 | old_inode, new_dentry->d_name.name, | ||
3508 | new_dentry->d_name.len, 1, index); | ||
3491 | if (ret) | 3509 | if (ret) |
3492 | goto out_fail; | 3510 | goto out_fail; |
3493 | 3511 | ||
@@ -3577,19 +3595,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
3577 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | 3595 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; |
3578 | inode->i_fop = &btrfs_file_operations; | 3596 | inode->i_fop = &btrfs_file_operations; |
3579 | inode->i_op = &btrfs_file_inode_operations; | 3597 | inode->i_op = &btrfs_file_inode_operations; |
3580 | extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); | ||
3581 | extent_io_tree_init(&BTRFS_I(inode)->io_tree, | ||
3582 | inode->i_mapping, GFP_NOFS); | ||
3583 | extent_io_tree_init(&BTRFS_I(inode)->io_failure_tree, | ||
3584 | inode->i_mapping, GFP_NOFS); | ||
3585 | INIT_LIST_HEAD(&BTRFS_I(inode)->delalloc_inodes); | ||
3586 | mutex_init(&BTRFS_I(inode)->csum_mutex); | ||
3587 | mutex_init(&BTRFS_I(inode)->extent_mutex); | ||
3588 | BTRFS_I(inode)->delalloc_bytes = 0; | ||
3589 | BTRFS_I(inode)->disk_i_size = 0; | ||
3590 | inode->i_mapping->writeback_index = 0; | ||
3591 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 3598 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
3592 | btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); | ||
3593 | } | 3599 | } |
3594 | dir->i_sb->s_dirt = 1; | 3600 | dir->i_sb->s_dirt = 1; |
3595 | btrfs_update_inode_block_group(trans, inode); | 3601 | btrfs_update_inode_block_group(trans, inode); |
@@ -3691,6 +3697,7 @@ static struct file_operations btrfs_dir_file_operations = { | |||
3691 | .compat_ioctl = btrfs_ioctl, | 3697 | .compat_ioctl = btrfs_ioctl, |
3692 | #endif | 3698 | #endif |
3693 | .release = btrfs_release_file, | 3699 | .release = btrfs_release_file, |
3700 | .fsync = btrfs_sync_file, | ||
3694 | }; | 3701 | }; |
3695 | 3702 | ||
3696 | static struct extent_io_ops btrfs_extent_io_ops = { | 3703 | static struct extent_io_ops btrfs_extent_io_ops = { |