aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/delayed-inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 19:41:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 19:41:54 -0500
commitb695188dd39162a1a6bff11fdbcc4c0b65b933ab (patch)
treea3df7c052d38b5bfaf335fbf3130abcc5c6ca577 /fs/btrfs/delayed-inode.c
parent48476df99894492a0f7239f2f3c9a2dde4ff38e2 (diff)
parent180e001cd5fc2950dc6a7997dde5b65c954d0e79 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs update from Chris Mason: "The biggest feature in the pull is the new (and still experimental) raid56 code that David Woodhouse started long ago. I'm still working on the parity logging setup that will avoid inconsistent parity after a crash, so this is only for testing right now. But, I'd really like to get it out to a broader audience to hammer out any performance issues or other problems. scrub does not yet correct errors on raid5/6 either. Josef has another pass at fsync performance. The big change here is to combine waiting for metadata with waiting for data, which is a big latency win. It is also step one toward using atomics from the hardware during a commit. Mark Fasheh has a new way to use btrfs send/receive to send only the metadata changes. SUSE is using this to make snapper more efficient at finding changes between snapshosts. Snapshot-aware defrag is also included. Otherwise we have a large number of fixes and cleanups. Eric Sandeen wins the award for removing the most lines, and I'm hoping we steal this idea from XFS over and over again." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (118 commits) btrfs: fixup/remove module.h usage as required Btrfs: delete inline extents when we find them during logging btrfs: try harder to allocate raid56 stripe cache Btrfs: cleanup to make the function btrfs_delalloc_reserve_metadata more logic Btrfs: don't call btrfs_qgroup_free if just btrfs_qgroup_reserve fails Btrfs: remove reduplicate check about root in the function btrfs_clean_quota_tree Btrfs: return ENOMEM rather than use BUG_ON when btrfs_alloc_path fails Btrfs: fix missing deleted items in btrfs_clean_quota_tree btrfs: use only inline_pages from extent buffer Btrfs: fix wrong reserved space when deleting a snapshot/subvolume Btrfs: fix wrong reserved space in qgroup during snap/subv creation Btrfs: remove unnecessary dget_parent/dput when creating the pending snapshot btrfs: remove a printk from scan_one_device Btrfs: fix NULL pointer after aborting a transaction Btrfs: fix memory leak of log roots Btrfs: copy everything if we've created an inline extent btrfs: cleanup for open-coded alignment Btrfs: do not change inode flags in rename Btrfs: use reserved space for creating a snapshot clear chunk_alloc flag on retryable failure ...
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r--fs/btrfs/delayed-inode.c147
1 files changed, 100 insertions, 47 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 34836036f01b..0b278b117cbe 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -875,7 +875,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
875 struct btrfs_delayed_item *delayed_item) 875 struct btrfs_delayed_item *delayed_item)
876{ 876{
877 struct extent_buffer *leaf; 877 struct extent_buffer *leaf;
878 struct btrfs_item *item;
879 char *ptr; 878 char *ptr;
880 int ret; 879 int ret;
881 880
@@ -886,7 +885,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
886 885
887 leaf = path->nodes[0]; 886 leaf = path->nodes[0];
888 887
889 item = btrfs_item_nr(leaf, path->slots[0]);
890 ptr = btrfs_item_ptr(leaf, path->slots[0], char); 888 ptr = btrfs_item_ptr(leaf, path->slots[0], char);
891 889
892 write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr, 890 write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr,
@@ -1065,32 +1063,25 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
1065 } 1063 }
1066} 1064}
1067 1065
1068static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, 1066static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1069 struct btrfs_root *root, 1067 struct btrfs_root *root,
1070 struct btrfs_path *path, 1068 struct btrfs_path *path,
1071 struct btrfs_delayed_node *node) 1069 struct btrfs_delayed_node *node)
1072{ 1070{
1073 struct btrfs_key key; 1071 struct btrfs_key key;
1074 struct btrfs_inode_item *inode_item; 1072 struct btrfs_inode_item *inode_item;
1075 struct extent_buffer *leaf; 1073 struct extent_buffer *leaf;
1076 int ret; 1074 int ret;
1077 1075
1078 mutex_lock(&node->mutex);
1079 if (!node->inode_dirty) {
1080 mutex_unlock(&node->mutex);
1081 return 0;
1082 }
1083
1084 key.objectid = node->inode_id; 1076 key.objectid = node->inode_id;
1085 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); 1077 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
1086 key.offset = 0; 1078 key.offset = 0;
1079
1087 ret = btrfs_lookup_inode(trans, root, path, &key, 1); 1080 ret = btrfs_lookup_inode(trans, root, path, &key, 1);
1088 if (ret > 0) { 1081 if (ret > 0) {
1089 btrfs_release_path(path); 1082 btrfs_release_path(path);
1090 mutex_unlock(&node->mutex);
1091 return -ENOENT; 1083 return -ENOENT;
1092 } else if (ret < 0) { 1084 } else if (ret < 0) {
1093 mutex_unlock(&node->mutex);
1094 return ret; 1085 return ret;
1095 } 1086 }
1096 1087
@@ -1105,11 +1096,47 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1105 1096
1106 btrfs_delayed_inode_release_metadata(root, node); 1097 btrfs_delayed_inode_release_metadata(root, node);
1107 btrfs_release_delayed_inode(node); 1098 btrfs_release_delayed_inode(node);
1108 mutex_unlock(&node->mutex);
1109 1099
1110 return 0; 1100 return 0;
1111} 1101}
1112 1102
1103static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1104 struct btrfs_root *root,
1105 struct btrfs_path *path,
1106 struct btrfs_delayed_node *node)
1107{
1108 int ret;
1109
1110 mutex_lock(&node->mutex);
1111 if (!node->inode_dirty) {
1112 mutex_unlock(&node->mutex);
1113 return 0;
1114 }
1115
1116 ret = __btrfs_update_delayed_inode(trans, root, path, node);
1117 mutex_unlock(&node->mutex);
1118 return ret;
1119}
1120
1121static inline int
1122__btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
1123 struct btrfs_path *path,
1124 struct btrfs_delayed_node *node)
1125{
1126 int ret;
1127
1128 ret = btrfs_insert_delayed_items(trans, path, node->root, node);
1129 if (ret)
1130 return ret;
1131
1132 ret = btrfs_delete_delayed_items(trans, path, node->root, node);
1133 if (ret)
1134 return ret;
1135
1136 ret = btrfs_update_delayed_inode(trans, node->root, path, node);
1137 return ret;
1138}
1139
1113/* 1140/*
1114 * Called when committing the transaction. 1141 * Called when committing the transaction.
1115 * Returns 0 on success. 1142 * Returns 0 on success.
@@ -1119,7 +1146,6 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1119static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, 1146static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1120 struct btrfs_root *root, int nr) 1147 struct btrfs_root *root, int nr)
1121{ 1148{
1122 struct btrfs_root *curr_root = root;
1123 struct btrfs_delayed_root *delayed_root; 1149 struct btrfs_delayed_root *delayed_root;
1124 struct btrfs_delayed_node *curr_node, *prev_node; 1150 struct btrfs_delayed_node *curr_node, *prev_node;
1125 struct btrfs_path *path; 1151 struct btrfs_path *path;
@@ -1142,15 +1168,8 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1142 1168
1143 curr_node = btrfs_first_delayed_node(delayed_root); 1169 curr_node = btrfs_first_delayed_node(delayed_root);
1144 while (curr_node && (!count || (count && nr--))) { 1170 while (curr_node && (!count || (count && nr--))) {
1145 curr_root = curr_node->root; 1171 ret = __btrfs_commit_inode_delayed_items(trans, path,
1146 ret = btrfs_insert_delayed_items(trans, path, curr_root, 1172 curr_node);
1147 curr_node);
1148 if (!ret)
1149 ret = btrfs_delete_delayed_items(trans, path,
1150 curr_root, curr_node);
1151 if (!ret)
1152 ret = btrfs_update_delayed_inode(trans, curr_root,
1153 path, curr_node);
1154 if (ret) { 1173 if (ret) {
1155 btrfs_release_delayed_node(curr_node); 1174 btrfs_release_delayed_node(curr_node);
1156 curr_node = NULL; 1175 curr_node = NULL;
@@ -1183,51 +1202,93 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
1183 return __btrfs_run_delayed_items(trans, root, nr); 1202 return __btrfs_run_delayed_items(trans, root, nr);
1184} 1203}
1185 1204
1186static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, 1205int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
1187 struct btrfs_delayed_node *node) 1206 struct inode *inode)
1188{ 1207{
1208 struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
1189 struct btrfs_path *path; 1209 struct btrfs_path *path;
1190 struct btrfs_block_rsv *block_rsv; 1210 struct btrfs_block_rsv *block_rsv;
1191 int ret; 1211 int ret;
1192 1212
1213 if (!delayed_node)
1214 return 0;
1215
1216 mutex_lock(&delayed_node->mutex);
1217 if (!delayed_node->count) {
1218 mutex_unlock(&delayed_node->mutex);
1219 btrfs_release_delayed_node(delayed_node);
1220 return 0;
1221 }
1222 mutex_unlock(&delayed_node->mutex);
1223
1193 path = btrfs_alloc_path(); 1224 path = btrfs_alloc_path();
1194 if (!path) 1225 if (!path)
1195 return -ENOMEM; 1226 return -ENOMEM;
1196 path->leave_spinning = 1; 1227 path->leave_spinning = 1;
1197 1228
1198 block_rsv = trans->block_rsv; 1229 block_rsv = trans->block_rsv;
1199 trans->block_rsv = &node->root->fs_info->delayed_block_rsv; 1230 trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv;
1200 1231
1201 ret = btrfs_insert_delayed_items(trans, path, node->root, node); 1232 ret = __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
1202 if (!ret)
1203 ret = btrfs_delete_delayed_items(trans, path, node->root, node);
1204 if (!ret)
1205 ret = btrfs_update_delayed_inode(trans, node->root, path, node);
1206 btrfs_free_path(path);
1207 1233
1234 btrfs_release_delayed_node(delayed_node);
1235 btrfs_free_path(path);
1208 trans->block_rsv = block_rsv; 1236 trans->block_rsv = block_rsv;
1237
1209 return ret; 1238 return ret;
1210} 1239}
1211 1240
1212int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, 1241int btrfs_commit_inode_delayed_inode(struct inode *inode)
1213 struct inode *inode)
1214{ 1242{
1243 struct btrfs_trans_handle *trans;
1215 struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); 1244 struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
1245 struct btrfs_path *path;
1246 struct btrfs_block_rsv *block_rsv;
1216 int ret; 1247 int ret;
1217 1248
1218 if (!delayed_node) 1249 if (!delayed_node)
1219 return 0; 1250 return 0;
1220 1251
1221 mutex_lock(&delayed_node->mutex); 1252 mutex_lock(&delayed_node->mutex);
1222 if (!delayed_node->count) { 1253 if (!delayed_node->inode_dirty) {
1223 mutex_unlock(&delayed_node->mutex); 1254 mutex_unlock(&delayed_node->mutex);
1224 btrfs_release_delayed_node(delayed_node); 1255 btrfs_release_delayed_node(delayed_node);
1225 return 0; 1256 return 0;
1226 } 1257 }
1227 mutex_unlock(&delayed_node->mutex); 1258 mutex_unlock(&delayed_node->mutex);
1228 1259
1229 ret = __btrfs_commit_inode_delayed_items(trans, delayed_node); 1260 trans = btrfs_join_transaction(delayed_node->root);
1261 if (IS_ERR(trans)) {
1262 ret = PTR_ERR(trans);
1263 goto out;
1264 }
1265
1266 path = btrfs_alloc_path();
1267 if (!path) {
1268 ret = -ENOMEM;
1269 goto trans_out;
1270 }
1271 path->leave_spinning = 1;
1272
1273 block_rsv = trans->block_rsv;
1274 trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv;
1275
1276 mutex_lock(&delayed_node->mutex);
1277 if (delayed_node->inode_dirty)
1278 ret = __btrfs_update_delayed_inode(trans, delayed_node->root,
1279 path, delayed_node);
1280 else
1281 ret = 0;
1282 mutex_unlock(&delayed_node->mutex);
1283
1284 btrfs_free_path(path);
1285 trans->block_rsv = block_rsv;
1286trans_out:
1287 btrfs_end_transaction(trans, delayed_node->root);
1288 btrfs_btree_balance_dirty(delayed_node->root);
1289out:
1230 btrfs_release_delayed_node(delayed_node); 1290 btrfs_release_delayed_node(delayed_node);
1291
1231 return ret; 1292 return ret;
1232} 1293}
1233 1294
@@ -1258,7 +1319,6 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
1258 struct btrfs_root *root; 1319 struct btrfs_root *root;
1259 struct btrfs_block_rsv *block_rsv; 1320 struct btrfs_block_rsv *block_rsv;
1260 int need_requeue = 0; 1321 int need_requeue = 0;
1261 int ret;
1262 1322
1263 async_node = container_of(work, struct btrfs_async_delayed_node, work); 1323 async_node = container_of(work, struct btrfs_async_delayed_node, work);
1264 1324
@@ -1277,14 +1337,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
1277 block_rsv = trans->block_rsv; 1337 block_rsv = trans->block_rsv;
1278 trans->block_rsv = &root->fs_info->delayed_block_rsv; 1338 trans->block_rsv = &root->fs_info->delayed_block_rsv;
1279 1339
1280 ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); 1340 __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
1281 if (!ret)
1282 ret = btrfs_delete_delayed_items(trans, path, root,
1283 delayed_node);
1284
1285 if (!ret)
1286 btrfs_update_delayed_inode(trans, root, path, delayed_node);
1287
1288 /* 1341 /*
1289 * Maybe new delayed items have been inserted, so we need requeue 1342 * Maybe new delayed items have been inserted, so we need requeue
1290 * the work. Besides that, we must dequeue the empty delayed nodes 1343 * the work. Besides that, we must dequeue the empty delayed nodes