Skip to content

Commit

Permalink
btrfs: balance filter: add limit of processed chunks
Browse files Browse the repository at this point in the history
This started as debugging helper, to watch the effects of converting
between raid levels on multiple devices, but could be useful standalone.

In my case the usage filter was not finegrained enough and led to
converting too many chunks at once. Another example use is in connection
with drange+devid or vrange filters that allow to work with a specific
chunk or even with a chunk on a given device.

The limit filter applies last, the value of 0 means no limiting.

CC: Ilya Dryomov <idryomov@gmail.com>
CC: Hugo Mills <hugo@carfax.org.uk>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
  • Loading branch information
David Sterba authored and Chris Mason committed Jun 10, 2014
1 parent fc19c5e commit 7d824b6
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 2 deletions.
7 changes: 6 additions & 1 deletion fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,10 @@ struct btrfs_disk_balance_args {
/* BTRFS_BALANCE_ARGS_* */
__le64 flags;

__le64 unused[8];
/* BTRFS_BALANCE_ARGS_LIMIT value */
__le64 limit;

__le64 unused[7];
} __attribute__ ((__packed__));

/*
Expand Down Expand Up @@ -2897,6 +2900,7 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu,
cpu->vend = le64_to_cpu(disk->vend);
cpu->target = le64_to_cpu(disk->target);
cpu->flags = le64_to_cpu(disk->flags);
cpu->limit = le64_to_cpu(disk->limit);
}

static inline void
Expand All @@ -2914,6 +2918,7 @@ btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk,
disk->vend = cpu_to_le64(cpu->vend);
disk->target = cpu_to_le64(cpu->target);
disk->flags = cpu_to_le64(cpu->flags);
disk->limit = cpu_to_le64(cpu->limit);
}

/* struct btrfs_super_block */
Expand Down
18 changes: 18 additions & 0 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2922,6 +2922,16 @@ static int should_balance_chunk(struct btrfs_root *root,
return 0;
}

/*
* limited by count, must be the last filter
*/
if ((bargs->flags & BTRFS_BALANCE_ARGS_LIMIT)) {
if (bargs->limit == 0)
return 0;
else
bargs->limit--;
}

return 1;
}

Expand All @@ -2944,6 +2954,9 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
int ret;
int enospc_errors = 0;
bool counting = true;
u64 limit_data = bctl->data.limit;
u64 limit_meta = bctl->meta.limit;
u64 limit_sys = bctl->sys.limit;

/* step one make some room on all the devices */
devices = &fs_info->fs_devices->devices;
Expand Down Expand Up @@ -2982,6 +2995,11 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
memset(&bctl->stat, 0, sizeof(bctl->stat));
spin_unlock(&fs_info->balance_lock);
again:
if (!counting) {
bctl->data.limit = limit_data;
bctl->meta.limit = limit_meta;
bctl->sys.limit = limit_sys;
}
key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
key.offset = (u64)-1;
key.type = BTRFS_CHUNK_ITEM_KEY;
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/volumes.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ struct map_lookup {
#define BTRFS_BALANCE_ARGS_DEVID (1ULL << 2)
#define BTRFS_BALANCE_ARGS_DRANGE (1ULL << 3)
#define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4)
#define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5)

/*
* Profile changing flags. When SOFT is set we won't relocate chunk if
Expand Down
3 changes: 2 additions & 1 deletion include/uapi/linux/btrfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ struct btrfs_balance_args {

__u64 flags;

__u64 unused[8];
__u64 limit; /* limit number of processed chunks */
__u64 unused[7];
} __attribute__ ((__packed__));

/* report balance progress to userspace */
Expand Down

0 comments on commit 7d824b6

Please sign in to comment.