@@ -875,8 +875,7 @@ static int btrfs_clean_quota_tree(struct btrfs_trans_handle *trans,
875
875
return ret ;
876
876
}
877
877
878
- int btrfs_quota_enable (struct btrfs_trans_handle * trans ,
879
- struct btrfs_fs_info * fs_info )
878
+ int btrfs_quota_enable (struct btrfs_fs_info * fs_info )
880
879
{
881
880
struct btrfs_root * quota_root ;
882
881
struct btrfs_root * tree_root = fs_info -> tree_root ;
@@ -886,16 +885,33 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
886
885
struct btrfs_key key ;
887
886
struct btrfs_key found_key ;
888
887
struct btrfs_qgroup * qgroup = NULL ;
888
+ struct btrfs_trans_handle * trans = NULL ;
889
889
int ret = 0 ;
890
890
int slot ;
891
891
892
892
mutex_lock (& fs_info -> qgroup_ioctl_lock );
893
893
if (fs_info -> quota_root )
894
894
goto out ;
895
895
896
+ /*
897
+ * 1 for quota root item
898
+ * 1 for BTRFS_QGROUP_STATUS item
899
+ *
900
+ * Yet we also need 2*n items for a QGROUP_INFO/QGROUP_LIMIT items
901
+ * per subvolume. However those are not currently reserved since it
902
+ * would be a lot of overkill.
903
+ */
904
+ trans = btrfs_start_transaction (tree_root , 2 );
905
+ if (IS_ERR (trans )) {
906
+ ret = PTR_ERR (trans );
907
+ trans = NULL ;
908
+ goto out ;
909
+ }
910
+
896
911
fs_info -> qgroup_ulist = ulist_alloc (GFP_KERNEL );
897
912
if (!fs_info -> qgroup_ulist ) {
898
913
ret = - ENOMEM ;
914
+ btrfs_abort_transaction (trans , ret );
899
915
goto out ;
900
916
}
901
917
@@ -906,12 +922,14 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
906
922
BTRFS_QUOTA_TREE_OBJECTID );
907
923
if (IS_ERR (quota_root )) {
908
924
ret = PTR_ERR (quota_root );
925
+ btrfs_abort_transaction (trans , ret );
909
926
goto out ;
910
927
}
911
928
912
929
path = btrfs_alloc_path ();
913
930
if (!path ) {
914
931
ret = - ENOMEM ;
932
+ btrfs_abort_transaction (trans , ret );
915
933
goto out_free_root ;
916
934
}
917
935
@@ -921,8 +939,10 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
921
939
922
940
ret = btrfs_insert_empty_item (trans , quota_root , path , & key ,
923
941
sizeof (* ptr ));
924
- if (ret )
942
+ if (ret ) {
943
+ btrfs_abort_transaction (trans , ret );
925
944
goto out_free_path ;
945
+ }
926
946
927
947
leaf = path -> nodes [0 ];
928
948
ptr = btrfs_item_ptr (leaf , path -> slots [0 ],
@@ -944,9 +964,10 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
944
964
ret = btrfs_search_slot_for_read (tree_root , & key , path , 1 , 0 );
945
965
if (ret > 0 )
946
966
goto out_add_root ;
947
- if (ret < 0 )
967
+ if (ret < 0 ) {
968
+ btrfs_abort_transaction (trans , ret );
948
969
goto out_free_path ;
949
-
970
+ }
950
971
951
972
while (1 ) {
952
973
slot = path -> slots [0 ];
@@ -956,37 +977,52 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
956
977
if (found_key .type == BTRFS_ROOT_REF_KEY ) {
957
978
ret = add_qgroup_item (trans , quota_root ,
958
979
found_key .offset );
959
- if (ret )
980
+ if (ret ) {
981
+ btrfs_abort_transaction (trans , ret );
960
982
goto out_free_path ;
983
+ }
961
984
962
985
qgroup = add_qgroup_rb (fs_info , found_key .offset );
963
986
if (IS_ERR (qgroup )) {
964
987
ret = PTR_ERR (qgroup );
988
+ btrfs_abort_transaction (trans , ret );
965
989
goto out_free_path ;
966
990
}
967
991
}
968
992
ret = btrfs_next_item (tree_root , path );
969
- if (ret < 0 )
993
+ if (ret < 0 ) {
994
+ btrfs_abort_transaction (trans , ret );
970
995
goto out_free_path ;
996
+ }
971
997
if (ret )
972
998
break ;
973
999
}
974
1000
975
1001
out_add_root :
976
1002
btrfs_release_path (path );
977
1003
ret = add_qgroup_item (trans , quota_root , BTRFS_FS_TREE_OBJECTID );
978
- if (ret )
1004
+ if (ret ) {
1005
+ btrfs_abort_transaction (trans , ret );
979
1006
goto out_free_path ;
1007
+ }
980
1008
981
1009
qgroup = add_qgroup_rb (fs_info , BTRFS_FS_TREE_OBJECTID );
982
1010
if (IS_ERR (qgroup )) {
983
1011
ret = PTR_ERR (qgroup );
1012
+ btrfs_abort_transaction (trans , ret );
984
1013
goto out_free_path ;
985
1014
}
986
1015
spin_lock (& fs_info -> qgroup_lock );
987
1016
fs_info -> quota_root = quota_root ;
988
1017
set_bit (BTRFS_FS_QUOTA_ENABLED , & fs_info -> flags );
989
1018
spin_unlock (& fs_info -> qgroup_lock );
1019
+
1020
+ ret = btrfs_commit_transaction (trans );
1021
+ if (ret ) {
1022
+ trans = NULL ;
1023
+ goto out_free_path ;
1024
+ }
1025
+
990
1026
ret = qgroup_rescan_init (fs_info , 0 , 1 );
991
1027
if (!ret ) {
992
1028
qgroup_rescan_zero_tracking (fs_info );
@@ -1006,20 +1042,35 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
1006
1042
if (ret ) {
1007
1043
ulist_free (fs_info -> qgroup_ulist );
1008
1044
fs_info -> qgroup_ulist = NULL ;
1045
+ if (trans )
1046
+ btrfs_end_transaction (trans );
1009
1047
}
1010
1048
mutex_unlock (& fs_info -> qgroup_ioctl_lock );
1011
1049
return ret ;
1012
1050
}
1013
1051
1014
- int btrfs_quota_disable (struct btrfs_trans_handle * trans ,
1015
- struct btrfs_fs_info * fs_info )
1052
+ int btrfs_quota_disable (struct btrfs_fs_info * fs_info )
1016
1053
{
1017
1054
struct btrfs_root * quota_root ;
1055
+ struct btrfs_trans_handle * trans = NULL ;
1018
1056
int ret = 0 ;
1019
1057
1020
1058
mutex_lock (& fs_info -> qgroup_ioctl_lock );
1021
1059
if (!fs_info -> quota_root )
1022
1060
goto out ;
1061
+
1062
+ /*
1063
+ * 1 For the root item
1064
+ *
1065
+ * We should also reserve enough items for the quota tree deletion in
1066
+ * btrfs_clean_quota_tree but this is not done.
1067
+ */
1068
+ trans = btrfs_start_transaction (fs_info -> tree_root , 1 );
1069
+ if (IS_ERR (trans )) {
1070
+ ret = PTR_ERR (trans );
1071
+ goto out ;
1072
+ }
1073
+
1023
1074
clear_bit (BTRFS_FS_QUOTA_ENABLED , & fs_info -> flags );
1024
1075
btrfs_qgroup_wait_for_completion (fs_info , false);
1025
1076
spin_lock (& fs_info -> qgroup_lock );
@@ -1031,12 +1082,16 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans,
1031
1082
btrfs_free_qgroup_config (fs_info );
1032
1083
1033
1084
ret = btrfs_clean_quota_tree (trans , quota_root );
1034
- if (ret )
1035
- goto out ;
1085
+ if (ret ) {
1086
+ btrfs_abort_transaction (trans , ret );
1087
+ goto end_trans ;
1088
+ }
1036
1089
1037
1090
ret = btrfs_del_root (trans , fs_info , & quota_root -> root_key );
1038
- if (ret )
1039
- goto out ;
1091
+ if (ret ) {
1092
+ btrfs_abort_transaction (trans , ret );
1093
+ goto end_trans ;
1094
+ }
1040
1095
1041
1096
list_del (& quota_root -> dirty_list );
1042
1097
@@ -1048,6 +1103,9 @@ int btrfs_quota_disable(struct btrfs_trans_handle *trans,
1048
1103
free_extent_buffer (quota_root -> node );
1049
1104
free_extent_buffer (quota_root -> commit_root );
1050
1105
kfree (quota_root );
1106
+
1107
+ end_trans :
1108
+ ret = btrfs_end_transaction (trans );
1051
1109
out :
1052
1110
mutex_unlock (& fs_info -> qgroup_ioctl_lock );
1053
1111
return ret ;
0 commit comments