diff options
| -rw-r--r-- | fs/btrfs/Makefile | 2 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 46 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 34 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.h | 24 | ||||
| -rw-r--r-- | fs/btrfs/qgroup.c | 1571 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/transaction.h | 3 |
7 files changed, 1681 insertions, 1 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 0c4fa2befae7..0bc4d3a10a5f 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
| @@ -8,7 +8,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ | |||
| 8 | extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ | 8 | extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ |
| 9 | export.o tree-log.o free-space-cache.o zlib.o lzo.o \ | 9 | export.o tree-log.o free-space-cache.o zlib.o lzo.o \ |
| 10 | compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ | 10 | compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ |
| 11 | reada.o backref.o ulist.o | 11 | reada.o backref.o ulist.o qgroup.o |
| 12 | 12 | ||
| 13 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o | 13 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o |
| 14 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o | 14 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a5269d4a164f..ccba9b684c96 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -2830,6 +2830,8 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, | |||
| 2830 | int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range); | 2830 | int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range); |
| 2831 | 2831 | ||
| 2832 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info); | 2832 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info); |
| 2833 | int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, | ||
| 2834 | struct btrfs_fs_info *fs_info); | ||
| 2833 | /* ctree.c */ | 2835 | /* ctree.c */ |
| 2834 | int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, | 2836 | int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, |
| 2835 | int level, int *slot); | 2837 | int level, int *slot); |
| @@ -3339,6 +3341,50 @@ void btrfs_reada_detach(void *handle); | |||
| 3339 | int btree_readahead_hook(struct btrfs_root *root, struct extent_buffer *eb, | 3341 | int btree_readahead_hook(struct btrfs_root *root, struct extent_buffer *eb, |
| 3340 | u64 start, int err); | 3342 | u64 start, int err); |
| 3341 | 3343 | ||
| 3344 | /* qgroup.c */ | ||
| 3345 | struct qgroup_update { | ||
| 3346 | struct list_head list; | ||
| 3347 | struct btrfs_delayed_ref_node *node; | ||
| 3348 | struct btrfs_delayed_extent_op *extent_op; | ||
| 3349 | }; | ||
| 3350 | |||
| 3351 | int btrfs_quota_enable(struct btrfs_trans_handle *trans, | ||
| 3352 | struct btrfs_fs_info *fs_info); | ||
| 3353 | int btrfs_quota_disable(struct btrfs_trans_handle *trans, | ||
| 3354 | struct btrfs_fs_info *fs_info); | ||
| 3355 | int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); | ||
| 3356 | int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, | ||
| 3357 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); | ||
| 3358 | int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, | ||
| 3359 | struct btrfs_fs_info *fs_info, u64 src, u64 dst); | ||
| 3360 | int btrfs_create_qgroup(struct btrfs_trans_handle *trans, | ||
| 3361 | struct btrfs_fs_info *fs_info, u64 qgroupid, | ||
| 3362 | char *name); | ||
| 3363 | int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, | ||
| 3364 | struct btrfs_fs_info *fs_info, u64 qgroupid); | ||
| 3365 | int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, | ||
| 3366 | struct btrfs_fs_info *fs_info, u64 qgroupid, | ||
| 3367 | struct btrfs_qgroup_limit *limit); | ||
| 3368 | int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info); | ||
| 3369 | void btrfs_free_qgroup_config(struct btrfs_fs_info *fs_info); | ||
| 3370 | struct btrfs_delayed_extent_op; | ||
| 3371 | int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans, | ||
| 3372 | struct btrfs_delayed_ref_node *node, | ||
| 3373 | struct btrfs_delayed_extent_op *extent_op); | ||
| 3374 | int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | ||
| 3375 | struct btrfs_fs_info *fs_info, | ||
| 3376 | struct btrfs_delayed_ref_node *node, | ||
| 3377 | struct btrfs_delayed_extent_op *extent_op); | ||
| 3378 | int btrfs_run_qgroups(struct btrfs_trans_handle *trans, | ||
| 3379 | struct btrfs_fs_info *fs_info); | ||
| 3380 | int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | ||
| 3381 | struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, | ||
| 3382 | struct btrfs_qgroup_inherit *inherit); | ||
| 3383 | int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes); | ||
| 3384 | void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes); | ||
| 3385 | |||
| 3386 | void assert_qgroups_uptodate(struct btrfs_trans_handle *trans); | ||
| 3387 | |||
| 3342 | static inline int is_fstree(u64 rootid) | 3388 | static inline int is_fstree(u64 rootid) |
| 3343 | { | 3389 | { |
| 3344 | if (rootid == BTRFS_FS_TREE_OBJECTID || | 3390 | if (rootid == BTRFS_FS_TREE_OBJECTID || |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b13f1fbc3733..1a63b830846d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -2409,6 +2409,40 @@ static u64 find_middle(struct rb_root *root) | |||
| 2409 | } | 2409 | } |
| 2410 | #endif | 2410 | #endif |
| 2411 | 2411 | ||
| 2412 | int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, | ||
| 2413 | struct btrfs_fs_info *fs_info) | ||
| 2414 | { | ||
| 2415 | struct qgroup_update *qgroup_update; | ||
| 2416 | int ret = 0; | ||
| 2417 | |||
| 2418 | if (list_empty(&trans->qgroup_ref_list) != | ||
| 2419 | !trans->delayed_ref_elem.seq) { | ||
| 2420 | /* list without seq or seq without list */ | ||
| 2421 | printk(KERN_ERR "btrfs: qgroup accounting update error, list is%s empty, seq is %llu\n", | ||
| 2422 | list_empty(&trans->qgroup_ref_list) ? "" : " not", | ||
| 2423 | trans->delayed_ref_elem.seq); | ||
| 2424 | BUG(); | ||
| 2425 | } | ||
| 2426 | |||
| 2427 | if (!trans->delayed_ref_elem.seq) | ||
| 2428 | return 0; | ||
| 2429 | |||
| 2430 | while (!list_empty(&trans->qgroup_ref_list)) { | ||
| 2431 | qgroup_update = list_first_entry(&trans->qgroup_ref_list, | ||
| 2432 | struct qgroup_update, list); | ||
| 2433 | list_del(&qgroup_update->list); | ||
| 2434 | if (!ret) | ||
| 2435 | ret = btrfs_qgroup_account_ref( | ||
| 2436 | trans, fs_info, qgroup_update->node, | ||
| 2437 | qgroup_update->extent_op); | ||
| 2438 | kfree(qgroup_update); | ||
| 2439 | } | ||
| 2440 | |||
| 2441 | btrfs_put_tree_mod_seq(fs_info, &trans->delayed_ref_elem); | ||
| 2442 | |||
| 2443 | return ret; | ||
| 2444 | } | ||
| 2445 | |||
| 2412 | /* | 2446 | /* |
| 2413 | * this starts processing the delayed reference count updates and | 2447 | * this starts processing the delayed reference count updates and |
| 2414 | * extent insertions we have queued up so far. count can be | 2448 | * extent insertions we have queued up so far. count can be |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index e440aa653c30..a8a2230f4c5c 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
| @@ -35,6 +35,30 @@ struct btrfs_ioctl_vol_args { | |||
| 35 | #define BTRFS_FSID_SIZE 16 | 35 | #define BTRFS_FSID_SIZE 16 |
| 36 | #define BTRFS_UUID_SIZE 16 | 36 | #define BTRFS_UUID_SIZE 16 |
| 37 | 37 | ||
| 38 | #define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0) | ||
| 39 | |||
| 40 | struct btrfs_qgroup_limit { | ||
| 41 | __u64 flags; | ||
| 42 | __u64 max_rfer; | ||
| 43 | __u64 max_excl; | ||
| 44 | __u64 rsv_rfer; | ||
| 45 | __u64 rsv_excl; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct btrfs_qgroup_inherit { | ||
| 49 | __u64 flags; | ||
| 50 | __u64 num_qgroups; | ||
| 51 | __u64 num_ref_copies; | ||
| 52 | __u64 num_excl_copies; | ||
| 53 | struct btrfs_qgroup_limit lim; | ||
| 54 | __u64 qgroups[0]; | ||
| 55 | }; | ||
| 56 | |||
| 57 | struct btrfs_ioctl_qgroup_limit_args { | ||
| 58 | __u64 qgroupid; | ||
| 59 | struct btrfs_qgroup_limit lim; | ||
| 60 | }; | ||
| 61 | |||
| 38 | #define BTRFS_SUBVOL_NAME_MAX 4039 | 62 | #define BTRFS_SUBVOL_NAME_MAX 4039 |
| 39 | struct btrfs_ioctl_vol_args_v2 { | 63 | struct btrfs_ioctl_vol_args_v2 { |
| 40 | __s64 fd; | 64 | __s64 fd; |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c new file mode 100644 index 000000000000..bc424ae5a81a --- /dev/null +++ b/fs/btrfs/qgroup.c | |||
| @@ -0,0 +1,1571 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 STRATO. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public | ||
| 6 | * License v2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public | ||
| 14 | * License along with this program; if not, write to the | ||
| 15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 16 | * Boston, MA 021110-1307, USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/sched.h> | ||
| 20 | #include <linux/pagemap.h> | ||
| 21 | #include <linux/writeback.h> | ||
| 22 | #include <linux/blkdev.h> | ||
| 23 | #include <linux/rbtree.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/workqueue.h> | ||
| 26 | |||
| 27 | #include "ctree.h" | ||
| 28 | #include "transaction.h" | ||
| 29 | #include "disk-io.h" | ||
| 30 | #include "locking.h" | ||
| 31 | #include "ulist.h" | ||
| 32 | #include "ioctl.h" | ||
| 33 | #include "backref.h" | ||
