diff options
-rw-r--r-- | fs/btrfs/delayed-inode.c | 90 | ||||
-rw-r--r-- | fs/btrfs/delayed-inode.h | 1 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 11 |
3 files changed, 85 insertions, 17 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 4e204bb8ba13..c7e75061b894 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -1065,32 +1065,25 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) | |||
1065 | } | 1065 | } |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | 1068 | static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, |
1069 | struct btrfs_root *root, | 1069 | struct btrfs_root *root, |
1070 | struct btrfs_path *path, | 1070 | struct btrfs_path *path, |
1071 | struct btrfs_delayed_node *node) | 1071 | struct btrfs_delayed_node *node) |
1072 | { | 1072 | { |
1073 | struct btrfs_key key; | 1073 | struct btrfs_key key; |
1074 | struct btrfs_inode_item *inode_item; | 1074 | struct btrfs_inode_item *inode_item; |
1075 | struct extent_buffer *leaf; | 1075 | struct extent_buffer *leaf; |
1076 | int ret; | 1076 | int ret; |
1077 | 1077 | ||
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; | 1078 | key.objectid = node->inode_id; |
1085 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 1079 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
1086 | key.offset = 0; | 1080 | key.offset = 0; |
1081 | |||
1087 | ret = btrfs_lookup_inode(trans, root, path, &key, 1); | 1082 | ret = btrfs_lookup_inode(trans, root, path, &key, 1); |
1088 | if (ret > 0) { | 1083 | if (ret > 0) { |
1089 | btrfs_release_path(path); | 1084 | btrfs_release_path(path); |
1090 | mutex_unlock(&node->mutex); | ||
1091 | return -ENOENT; | 1085 | return -ENOENT; |
1092 | } else if (ret < 0) { | 1086 | } else if (ret < 0) { |
1093 | mutex_unlock(&node->mutex); | ||
1094 | return ret; | 1087 | return ret; |
1095 | } | 1088 | } |
1096 | 1089 | ||
@@ -1105,11 +1098,28 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | |||
1105 | 1098 | ||
1106 | btrfs_delayed_inode_release_metadata(root, node); | 1099 | btrfs_delayed_inode_release_metadata(root, node); |
1107 | btrfs_release_delayed_inode(node); | 1100 | btrfs_release_delayed_inode(node); |
1108 | mutex_unlock(&node->mutex); | ||
1109 | 1101 | ||
1110 | return 0; | 1102 | return 0; |
1111 | } | 1103 | } |
1112 | 1104 | ||
1105 | static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, | ||
1106 | struct btrfs_root *root, | ||
1107 | struct btrfs_path *path, | ||
1108 | struct btrfs_delayed_node *node) | ||
1109 | { | ||
1110 | int ret; | ||
1111 | |||
1112 | mutex_lock(&node->mutex); | ||
1113 | if (!node->inode_dirty) { | ||
1114 | mutex_unlock(&node->mutex); | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | ret = __btrfs_update_delayed_inode(trans, root, path, node); | ||
1119 | mutex_unlock(&node->mutex); | ||
1120 | return ret; | ||
1121 | } | ||
1122 | |||
1113 | static inline int | 1123 | static inline int |
1114 | __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | 1124 | __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, |
1115 | struct btrfs_path *path, | 1125 | struct btrfs_path *path, |
@@ -1230,6 +1240,60 @@ int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
1230 | return ret; | 1240 | return ret; |
1231 | } | 1241 | } |
1232 | 1242 | ||
1243 | int btrfs_commit_inode_delayed_inode(struct inode *inode) | ||
1244 | { | ||
1245 | struct btrfs_trans_handle *trans; | ||
1246 | struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); | ||
1247 | struct btrfs_path *path; | ||
1248 | struct btrfs_block_rsv *block_rsv; | ||
1249 | int ret; | ||
1250 | |||
1251 | if (!delayed_node) | ||
1252 | return 0; | ||
1253 | |||
1254 | mutex_lock(&delayed_node->mutex); | ||
1255 | if (!delayed_node->inode_dirty) { | ||
1256 | mutex_unlock(&delayed_node->mutex); | ||
1257 | btrfs_release_delayed_node(delayed_node); | ||
1258 | return 0; | ||
1259 | } | ||
1260 | mutex_unlock(&delayed_node->mutex); | ||
1261 | |||
1262 | trans = btrfs_join_transaction(delayed_node->root); | ||
1263 | if (IS_ERR(trans)) { | ||
1264 | ret = PTR_ERR(trans); | ||
1265 | goto out; | ||
1266 | } | ||
1267 | |||
1268 | path = btrfs_alloc_path(); | ||
1269 | if (!path) { | ||
1270 | ret = -ENOMEM; | ||
1271 | goto trans_out; | ||
1272 | } | ||
1273 | path->leave_spinning = 1; | ||
1274 | |||
1275 | block_rsv = trans->block_rsv; | ||
1276 | trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv; | ||
1277 | |||
1278 | mutex_lock(&delayed_node->mutex); | ||
1279 | if (delayed_node->inode_dirty) | ||
1280 | ret = __btrfs_update_delayed_inode(trans, delayed_node->root, | ||
1281 | path, delayed_node); | ||
1282 | else | ||
1283 | ret = 0; | ||
1284 | mutex_unlock(&delayed_node->mutex); | ||
1285 | |||
1286 | btrfs_free_path(path); | ||
1287 | trans->block_rsv = block_rsv; | ||
1288 | trans_out: | ||
1289 | btrfs_end_transaction(trans, delayed_node->root); | ||
1290 | btrfs_btree_balance_dirty(delayed_node->root); | ||
1291 | out: | ||
1292 | btrfs_release_delayed_node(delayed_node); | ||
1293 | |||
1294 | return ret; | ||
1295 | } | ||
1296 | |||
1233 | void btrfs_remove_delayed_node(struct inode *inode) | 1297 | void btrfs_remove_delayed_node(struct inode *inode) |
1234 | { | 1298 | { |
1235 | struct btrfs_delayed_node *delayed_node; | 1299 | struct btrfs_delayed_node *delayed_node; |
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h index 4f808e1baeed..78b6ad0fc669 100644 --- a/fs/btrfs/delayed-inode.h +++ b/fs/btrfs/delayed-inode.h | |||
@@ -117,6 +117,7 @@ int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, | |||
117 | /* Used for evicting the inode. */ | 117 | /* Used for evicting the inode. */ |
118 | void btrfs_remove_delayed_node(struct inode *inode); | 118 | void btrfs_remove_delayed_node(struct inode *inode); |
119 | void btrfs_kill_delayed_inode_items(struct inode *inode); | 119 | void btrfs_kill_delayed_inode_items(struct inode *inode); |
120 | int btrfs_commit_inode_delayed_inode(struct inode *inode); | ||
120 | 121 | ||
121 | 122 | ||
122 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | 123 | int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ca7ace7b7b52..1ea0988b82e1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3904,6 +3904,12 @@ void btrfs_evict_inode(struct inode *inode) | |||
3904 | goto no_delete; | 3904 | goto no_delete; |
3905 | } | 3905 | } |
3906 | 3906 | ||
3907 | ret = btrfs_commit_inode_delayed_inode(inode); | ||
3908 | if (ret) { | ||
3909 | btrfs_orphan_del(NULL, inode); | ||
3910 | goto no_delete; | ||
3911 | } | ||
3912 | |||
3907 | rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP); | 3913 | rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP); |
3908 | if (!rsv) { | 3914 | if (!rsv) { |
3909 | btrfs_orphan_del(NULL, inode); | 3915 | btrfs_orphan_del(NULL, inode); |
@@ -3941,7 +3947,7 @@ void btrfs_evict_inode(struct inode *inode) | |||
3941 | goto no_delete; | 3947 | goto no_delete; |
3942 | } | 3948 | } |
3943 | 3949 | ||
3944 | trans = btrfs_start_transaction_lflush(root, 1); | 3950 | trans = btrfs_join_transaction(root); |
3945 | if (IS_ERR(trans)) { | 3951 | if (IS_ERR(trans)) { |
3946 | btrfs_orphan_del(NULL, inode); | 3952 | btrfs_orphan_del(NULL, inode); |
3947 | btrfs_free_block_rsv(root, rsv); | 3953 | btrfs_free_block_rsv(root, rsv); |
@@ -3955,9 +3961,6 @@ void btrfs_evict_inode(struct inode *inode) | |||
3955 | break; | 3961 | break; |
3956 | 3962 | ||
3957 | trans->block_rsv = &root->fs_info->trans_block_rsv; | 3963 | trans->block_rsv = &root->fs_info->trans_block_rsv; |
3958 | ret = btrfs_update_inode(trans, root, inode); | ||
3959 | BUG_ON(ret); | ||
3960 | |||
3961 | btrfs_end_transaction(trans, root); | 3964 | btrfs_end_transaction(trans, root); |
3962 | trans = NULL; | 3965 | trans = NULL; |
3963 | btrfs_btree_balance_dirty(root); | 3966 | btrfs_btree_balance_dirty(root); |