5959#include "mkfs/common.h"
6060#include "mkfs/rootdir.h"
6161
62+ #include "libbtrfs/ctree.h"
63+
6264struct mkfs_allocation {
6365 u64 data ;
6466 u64 metadata ;
@@ -882,6 +884,51 @@ static int insert_qgroup_items(struct btrfs_trans_handle *trans,
882884 return ret ;
883885}
884886
887+ /*
888+ * Workaround for squota so the enable_gen can be properly used.
889+ */
890+ static int touch_root_subvol (struct btrfs_fs_info * fs_info )
891+ {
892+ struct btrfs_trans_handle * trans ;
893+ struct btrfs_key key = {
894+ .objectid = BTRFS_FIRST_FREE_OBJECTID ,
895+ .type = BTRFS_INODE_ITEM_KEY ,
896+ .offset = 0 ,
897+ };
898+ struct extent_buffer * leaf ;
899+ int slot ;
900+ struct btrfs_path path ;
901+ int ret ;
902+
903+ trans = btrfs_start_transaction (fs_info -> fs_root , 1 );
904+ if (IS_ERR (trans )) {
905+ ret = PTR_ERR (trans );
906+ errno = - ret ;
907+ error_msg (ERROR_MSG_START_TRANS , "%m" );
908+ return ret ;
909+ }
910+ btrfs_init_path (& path );
911+ ret = btrfs_search_slot (trans , fs_info -> fs_root , & key , & path , 0 , 1 );
912+ if (ret )
913+ goto fail ;
914+ leaf = path .nodes [0 ];
915+ slot = path .slots [0 ];
916+ btrfs_item_key_to_cpu (leaf , & key , slot );
917+ btrfs_mark_buffer_dirty (leaf );
918+ ret = btrfs_commit_transaction (trans , fs_info -> fs_root );
919+ if (ret < 0 ) {
920+ errno = - ret ;
921+ error_msg (ERROR_MSG_COMMIT_TRANS , "%m" );
922+ return ret ;
923+ }
924+ btrfs_release_path (& path );
925+ return 0 ;
926+ fail :
927+ btrfs_abort_transaction (trans , ret );
928+ btrfs_release_path (& path );
929+ return ret ;
930+ }
931+
885932static int setup_quota_root (struct btrfs_fs_info * fs_info )
886933{
887934 struct btrfs_trans_handle * trans ;
@@ -890,8 +937,11 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
890937 struct btrfs_path path ;
891938 struct btrfs_key key ;
892939 int qgroup_repaired = 0 ;
940+ bool simple = btrfs_fs_incompat (fs_info , SIMPLE_QUOTA );
941+ int flags ;
893942 int ret ;
894943
944+
895945 /* One to modify tree root, one for quota root */
896946 trans = btrfs_start_transaction (fs_info -> tree_root , 2 );
897947 if (IS_ERR (trans )) {
@@ -921,13 +971,19 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
921971
922972 qsi = btrfs_item_ptr (path .nodes [0 ], path .slots [0 ],
923973 struct btrfs_qgroup_status_item );
924- btrfs_set_qgroup_status_generation (path .nodes [0 ], qsi , 0 );
974+ btrfs_set_qgroup_status_generation (path .nodes [0 ], qsi , trans -> transid );
925975 btrfs_set_qgroup_status_rescan (path .nodes [0 ], qsi , 0 );
976+ flags = BTRFS_QGROUP_STATUS_FLAG_ON ;
977+ if (simple ) {
978+ btrfs_set_qgroup_status_enable_gen (path .nodes [0 ], qsi , trans -> transid );
979+ flags |= BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE ;
980+ }
981+ else {
982+ flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
983+ }
926984
927- /* Mark current status info inconsistent, and fix it later */
928- btrfs_set_qgroup_status_flags (path .nodes [0 ], qsi ,
929- BTRFS_QGROUP_STATUS_FLAG_ON |
930- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT );
985+ btrfs_set_qgroup_status_version (path .nodes [0 ], qsi , 1 );
986+ btrfs_set_qgroup_status_flags (path .nodes [0 ], qsi , flags );
931987 btrfs_release_path (& path );
932988
933989 /* Currently mkfs will only create one subvolume */
@@ -944,6 +1000,15 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
9441000 return ret ;
9451001 }
9461002
1003+ /* Hack to count the default subvol metadata by dirtying it */
1004+ if (simple ) {
1005+ ret = touch_root_subvol (fs_info );
1006+ if (ret ) {
1007+ error ("failed to touch root dir for simple quota accounting %d (%m)" , ret );
1008+ goto fail ;
1009+ }
1010+ }
1011+
9471012 /*
9481013 * Qgroup is setup but with wrong info, use qgroup-verify
9491014 * infrastructure to repair them. (Just acts as offline rescan)
@@ -1813,7 +1878,8 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
18131878 }
18141879 }
18151880
1816- if (features .runtime_flags & BTRFS_FEATURE_RUNTIME_QUOTA ) {
1881+ if (features .runtime_flags & BTRFS_FEATURE_RUNTIME_QUOTA ||
1882+ features .incompat_flags & BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA ) {
18171883 ret = setup_quota_root (fs_info );
18181884 if (ret < 0 ) {
18191885 error ("failed to initialize quota: %d (%m)" , ret );
0 commit comments